WordPress「アップロード権限がありません」エラーの直し方
結論: このエラーは iPhone アプリやブラウザ、スクリプト側ではなく、WordPress サーバー側から返されています。最も多い原因は次の 2 つです:(1) Application Password に紐づくユーザーが upload_files capability を持っていない、(2) セキュリティプラグインや WAF が WordPress に届く前に /wp-json/wp/v2/media をブロックしている。ユーザーを Author(または upload_files を含む任意のロール)に昇格させるか、該当のファイアウォールルールから media エンドポイントを除外すれば、すぐにアップロードが動きます。
WordPress 6.7 にて 2026 年 6 月 2 日に動作検証済み。2026 年 7 月 22 日、緊急セキュリティパッチに起因するケース(Root Cause 5)を追加。
クイック診断:レスポンスから原因を読み取る
何かを変更する前に、クライアントが受け取っている HTTP レスポンスを確認してください。ステータスコードとエラーボディの組み合わせで、根本原因がほぼ特定できます。
| HTTP status | Error code | 想定される原因 | 最初に試すこと |
|---|---|---|---|
| 403 | rest_cannot_create | ユーザーロールに upload_files がない | ロールを Author 以上へ変更(Root Cause 1 参照) |
| 401 | rest_invalid_authentication | Application Password が誤っているか revoke 済み | Application Password を再発行(Root Cause 4 参照) |
| 403 | HTML ページ(JSON ではない) | セキュリティプラグインまたは WAF がブロック | Wordfence/iThemes/Cloudflare のイベントログを確認 |
| 503 / timeout | (ボディなし) | WAF やレートリミッタが接続を破棄 | Cloudflare またはオリジン側ファイアウォールのログを確認 |
| 200 | HTML ページ(JSON ではない) | プラグインで WP REST API が無効化されている | 「Disable REST API」系プラグインを無効化 |
このエラーがクライアントに届くまで
クライアントが WordPress に写真をアップロードするとき、リクエストは /wp-json/wp/v2/media への POST として送られます。リクエストにはユーザー名と Application Password を含む Authorization ヘッダーが付与されます。Application Password は Users → Profile → Application Passwords で発行するトークンで、WordPress 5.6 以降のコア機能です(公式インテグレーションガイド)。
WordPress コアはファイルを受け付ける前に permission check を実行します。WP_REST_Attachments_Controller::create_item_permissions_check() 内の該当ロジックは次のとおりです:
if ( ! current_user_can( 'upload_files' ) ) {
return new WP_Error(
'rest_cannot_create',
__( 'Sorry, you are not allowed to upload media on this site.' ),
array( 'status' => rest_authorization_required_code() )
);
} Application Password に紐づくユーザーが upload_files capability を持っていない場合、WordPress は HTTP 403 を返し、JSON ボディに "code": "rest_cannot_create" を含めます。クライアントはこのレスポンスを受け取り、「アップロード権限がありません」として表示します。
つまりこのメッセージは文字通りで、WordPress 自身が「このユーザーにはアップロードを許可していない」と言っています。次に必要なのはなぜそう判断されたのかを突き止めることです。ロール capability の一覧は 公式の Roles and Capabilities ページに掲載されています。
Root Cause 1:ユーザーロールに upload_files がない
これは SnapPress のサポートケースで最も多く観測される原因です。WordPress のデフォルトロールは 5 つで、メディアアップロードができるのは一部だけです:
| Role | メディアアップロード可否 |
|---|---|
| Administrator | 可 |
| Editor | 可 |
| Author | 可 |
| Contributor | 不可 |
| Subscriber | 不可 |
Application Password が Contributor または Subscriber に属している場合、認証自体は成功してもアップロードは必ず失敗します(パスワードは正しいが、その権限では足りないという状態です)。
ロールを確認する方法
https://your-site.example/wp-admin/で WordPress 管理画面にログインします。- Users → All Users を開きます。
- クライアントアプリに登録した Application Password の持ち主を探します。
- Role 列を確認します。
ロールが Contributor、Subscriber、あるいは upload_files を含まないカスタムロールであれば、原因はそれです。
修正方法(最小権限を優先)
最も安全な修正は、ユーザーを Author に昇格させることです。Author は upload_files を持ち、自身の投稿を作成・公開できる最小のデフォルトロールです。他ユーザーやプラグイン、設定の管理はできないため、アップロード用途だけが必要な場合の推奨ロールです。
他の Author の投稿を編集・公開する必要があれば Editor、サイト全体の管理が本当に必要な場合(たとえば自分一人で運用している自己所有サイト)にのみ Administrator へ昇格してください。ロール変更後は、正しくなったユーザーで新しい Application Password を発行し、クライアントアプリを更新してください。新規発行は厳密には必須ではありませんが、「古い認証情報が残っている」という仮説を消すために推奨されます。
カスタムロールを使っている場合
サイトで Members や User Role Editor のようなロールプラグインを使っている場合、ロール名はデフォルトと一致しないことがあります。ロールエディタを開き、対象ユーザーに割り当てられたロールを探し、upload_files のチェックボックスが有効になっているか確認してください。保存して再試行します。アップロードがある日突然動かなくなった場合、プラグイン更新によるカスタムロールの権限退行がいちばん怪しいので、ここから調べてください。複数ユーザーで運用するサイトでは、upload_files と最小限の投稿系 capability だけを持つ専用のカスタムロールを作るのが最もきれいです。
Root Cause 2:セキュリティプラグインが REST API をブロックしている
ユーザーロールが upload_files を含んでいるのにアップロードが失敗する場合、次に疑うのは WordPress コアが処理する前に REST API リクエストを止めるセキュリティプラグインです。代表的なものは:
- Wordfence — ファイアウォールルールが普通でない Authorization ヘッダーにマッチすることがあり、Rate Limiting が REST トラフィックをスロットルすることもあります。
- iThemes Security / Solid Security — REST API ハードニングのオプションにより、ブラウザのログイン済みセッション以外からの
/wp-json/wp/v2/*を拒否することがあります。 - Disable REST API — 名前のとおり、デフォルトで全 REST エンドポイントをブロックします。アプリからアップロードするには
/wp/v2/mediaをホワイトリストする必要があります。 - SecuPress、Shield Security なども同等の設定を持っています。
これらにブロックされると、プラグインが返す 403 が WordPress 本体のエラーに似ているため、「アップロード権限がない」という同じ症状に見えます。違いは、コアの current_user_can() チェックがそもそも走っていないことです。
Wordfence の確認ポイント
確認すべき設定は 2 つあります。Wordfence → All Options → Firewall Options を開きます:
- Brute Force Protection:厳しい lockout 設定だと、1 回のリトライで Application Password が一気にロックされることがあります。
- Rate Limiting:「If anyone's requests exceed...」のしきい値は REST トラフィックにも適用されます。失敗したアップロードをリトライするモバイルアプリがこれに引っかかることがあります。
Wordfence を疑う場合、Wordfence → Tools → Live Traffic を開いた状態でクライアントからアップロードをトリガーしてください。リクエストがブロックされていれば、発火したルールがログエントリに表示されます。ファイアウォールの全リファレンスは wordfence.com/help/firewall/ にあります。
iThemes Security / Solid Security の確認ポイント
Solid Security はリリースごとに REST API ハードニングの場所を移動させてきました。最近のバージョンでは Security → Settings → Advanced → WordPress Tweaks 配下に REST API オプションがあります(古いビルドでは Tools 配下にありました)。重要なのは次の 2 つの状態です:
- Default(REST API enabled) — アプリからのアップロードに必要な状態。
- Restricted — REST エンドポイントをログイン済みブラウザセッションに限定します。Application Password のリクエストはここで失敗します。
可能なら Default に戻す、もしくは /wp/v2/media を明示的にホワイトリストしてください。ラベル名はバージョンによって異なるので、ご利用バージョンの Solid Security ドキュメントを参照してください。
切り分けの手順
怪しいプラグインを 1 つずつ無効化し、その都度アップロードを試します。無効化した瞬間にアップロードが通るようになったものが犯人です。特定できたら、その中で REST API をブロックしている具体的な設定を見つけ、/wp-json/wp/v2/media をそこから除外してください。上記のプラグインはいずれも、メニューの場所はバージョンごとに違うものの、エンドポイント単位の除外設定をなんらかの形でサポートしています。
Root Cause 3:WAF がリクエストをブロックしている
サイトが WAF(Cloudflare WAF、Sucuri、AWS WAF、BunkerWeb など)の背後にある場合、アップロードリクエストが WordPress サーバーに到達する前に WAF が拒否することがあります。特に Cloudflare の WAF managed rules には、大きな multipart POST ボディや変則的な Content-Type の組み合わせをターゲットにするルールがあり、メディアアップロードはその両方を使います。ルールカタログは Cloudflare の WAF ドキュメントを参照してください。
症状はさまざまですが、典型的には次のいずれかです:
- レスポンスボディに Cloudflare のエラーページが入った HTTP 403。
- HTTP 503 もしくはタイムアウト(ボディなし)。
- JSON ではなく HTML が返る HTTP 200。
Cloudflare 向けの絞り込んだ修正
Cloudflare の managed rules を一括で無効化しないでください。代わりに、実際に発火しているルールを特定します:
- Cloudflare ダッシュボードで Security → Events(旧 Firewall Events)を開きます。
- クライアントから失敗するアップロードをトリガーします。
- ホスト名または URI
/wp-json/wp/v2/mediaでイベントを絞り込みます。ブロックしたルールが ruleset ID と rule ID 付きで表示されます。 - Security → WAF → Custom Rules でカスタムルールを作成し、特定したそのルールだけをアップロードエンドポイント向けに Skip させます:
(http.request.uri.path eq "/wp-json/wp/v2/media") and (http.request.method eq "POST") アクションは「Skip」とし、対象は特定した ruleset/rule に限定してください(managed challenge をまとめて Skip しない)。優先度は「Block」系ルールより上に置きます。これで /wp-json/ の残りに対する保護は維持したまま、正規のメディアアップロードだけを通せます。
Root Cause 4:認証失敗または Application Password が revoke されている
Application Password には期限切れフィールドがありません。発行後は手動で revoke するまで有効です。したがってこのケースの症状は通常、403 の権限エラーではなく HTTP 401 と rest_invalid_authentication です。とはいえ他のどれにも当てはまらないときは確認の価値があります:
- WordPress 管理画面 → Users → Profile → Application Passwords を開きます。
- クライアントアプリに登録したパスワードが今もリストにあるか確認します。
- 削除されていれば(手動、セキュリティプラグイン、またはパスワード変更イベントなどで)、新しく発行してクライアントを更新します。
- サイトが HTTPS で到達可能か確認します。WordPress はセキュリティ上、プレーン HTTP では Authorization ヘッダーを剥がします。http と https が混在していると断続的な 401 を引き起こします。
- セキュリティプラグインやカスタムコードが
wp_is_application_passwords_availableフィルタで Application Passwords を無効化していないことを確認します。
セキュリティプラグインの中には、パスワード変更・ロール変更・不審な挙動などのイベントで Application Password を自動的に revoke するものがあります。最近ロールを変更したばかりであれば、それだけで既存のパスワードが revoke されている可能性があります。再発行は 1 分で終わります。
Root Cause 5:緊急セキュリティパッチが一夜にしてルールを変えた
ここまでの 4 つの原因は、いずれも「サイトの誰か(あなた自身、または管理権限を持つ人)が意図的に変更した何か」を前提にしています。しかし SnapPress のサポート相談では、これとは違うパターンも増えています。何週間、何ヶ月も問題なくアップロードできていたのに、ある日突然 rest_cannot_create で失敗するようになり、サイト所有者側では意図的な設定変更を一切していない、というケースです。
このパターンの引き金は、多くの場合サイト所有者が直接始めたわけではない緊急アップデートです。WordPress コアで重大な脆弱性が公表されると、数時間以内に 2 つのことが起こりがちです。WordPress 自体がセキュリティリリースを出すこと、そしてセキュリティプラグインのベンダー(Wordfence、iThemes/Solid Security など)が、稼働中の全サイトに向けて更新済みのファイアウォールルールを、自動バックグラウンド更新で配信することです。直近の例では、2026 年 7 月 17 日に WordPress が「wp2shell」(CVE-2026-63030)と呼ばれる重大な REST API 脆弱性を公表し、同日中に WordPress 6.8.6/6.9.5/7.0.2 をリリースしました。主要な WAF ベンダー各社も、公表から数時間以内に新しい REST API ファイアウォールルールを配信しています。
こうした緊急ルールは通常、対象範囲を狭く絞って設計されます(このケースでは単一のバッチ処理エンドポイントが対象でした)。ただし、より広範・保守的なファイアウォール設定になっている場合、/wp-json/wp/v2/media のような他の REST API トラフィックまで巻き込んでブロックしてしまう可能性があります。これとは別に、一部のセキュリティプラグインには「Application Password を無効化する」という文字どおりのスイッチが用意されており(Wordfence の場合:Firewall → All Firewall Options → Brute Force Protection → Disable WordPress application passwords)、これがハードニング更新の一環としてオンに切り替わることがあります。この場合、ユーザーのロールは一切変わっていなくても、Root Cause 1 で説明したのとまったく同じ rest_cannot_create の症状が出ます。
自分のケースがこれに当てはまるか確認する方法
- アップロードが失敗し始めた正確な日付を控えます。
- WordPress 管理画面の ダッシュボード → 更新 を開き、WordPress コアのバージョンと更新履歴をその日付と照らし合わせます。
- セキュリティプラグインの変更履歴(changelog)や更新ログを確認します。多くのプラグインは自身の設定画面、または プラグイン → インストール済みプラグイン で確認できます。
- Wordfence を使っている場合、Firewall Options の Brute Force Protection にある Disable WordPress application passwords がオフになっていることを確認します。
- プラグインの更新日と障害発生日が一致する場合、一時的にロールバックまたは無効化して確認し、原因が特定できたら該当の REST API 制限機能だけをオフにして再度有効化してください(無効化したままにしない)。
この Root Cause 5 は、これまでの 4 つの原因に取って代わるものではありません。「昨日まで正しく設定されていたサイトが、なぜ今日になって失敗するのか」を説明するものです。根本的な直し方は、依然として Root Cause 1〜4 のいずれかです。このセクションは、意図的な変更が何もない場合に、どれを先に疑うべきかを素早く絞り込むためのものです。
コマンドラインで修正を検証する
修正を適用したら、クライアントアプリを使わずにアップロードが動くか検証できます。curl が使える環境から次を実行します:
curl -u 'your-username:your-application-password' \
-X POST \
-H 'Content-Disposition: attachment; filename=test.jpg' \
-H 'Content-Type: image/jpeg' \
--data-binary @test.jpg \
https://your-site.example/wp-json/wp/v2/media アップロードが成功すれば、HTTP 201 と、新しいメディアアイテムの id、source_url、media_details を含む JSON ボディが返ります。それ以外は記事冒頭の診断表に戻ってください。レスポンスボディがどの行に該当するかをほぼ教えてくれます。
curl が使えなければ、Postman など Basic 認証と multipart form data をサポートする HTTP クライアントでも同じテストが可能です。エンドポイント、認証情報、期待されるレスポンスはまったく同じです。
モバイルアプリ側ではこの問題を直せない理由
アップロードの不具合はアプリ側のバグだと考えたくなります。アプリが目に見える部分だからです。しかし WordPress REST API はあらゆるクライアント(ブラウザ、iOS アプリ、Zapier、コマンドライン)に対する唯一の権威ある gatekeeper です。アプリの役割は、妥当な形式のリクエストを正しい認証情報で送り、レスポンスを表示することです。WordPress が「アップロード権限なし」と言う以上、アプリを変えてもその答えは変わりません。修正は必ず WordPress 側(ロール、プラグイン設定、WAF ルール、Application Password)で行います。
これは設計上の意図であり、REST API モデルの強みでもあります。同じチェックが、スマホアプリでもデスクトップクライアントでも自作スクリプトでもサイトを保護してくれます。
まとめチェックリスト
- 実際のレスポンスから HTTP ステータスコードとエラーコードを読み取り、冒頭の診断表に照らす。
- WordPress ユーザーロールを確認する。デフォルトロールの中では
upload_filesを含むのは Author 以上。 - ロールが正しければ、セキュリティプラグインを 1 つずつ無効化してアップロードを再試行する。
- 原因のプラグインがなければ、WAF のイベントログを確認し、発火している具体的なルールに対してのみ
/wp-json/wp/v2/mediaの例外を追加する。 - Application Password がユーザープロフィールに残っていること、サイトが HTTPS であることを確認し、必要なら再発行する。
- クライアントアプリに戻る前に curl で end-to-end の動作確認をする。
- 意図的な変更が何もない場合は、障害発生日と WordPress コア/セキュリティプラグインの更新ログを照らし合わせる。緊急パッチが原因である可能性が最も高い。
この順で進めれば、SnapPress に寄せられる「アップロード権限なし」の報告はほとんど解消します。エラーメッセージは正しく仕事をしてくれています。あとはその文脈を読み解けば対処できる、それだけの問題です。
Frequently Asked Questions
- WordPress が iPhone アプリに『アップロード権限がありません』を返すのはなぜですか?
- REST API エンドポイント
/wp-json/wp/v2/mediaは、WordPress ユーザーがupload_filescapability を保持していることを要求します。Subscriber と Contributor ロールはこの capability を持ちません。iPhone アプリがこれらのロールのユーザーで認証している場合、アップロードを試みるたびに HTTP 403 がエラーコードrest_cannot_createとともに返されます。ユーザーを Author(またはupload_filesを含む任意のロール)に昇格させれば解決します。 - サイト管理者なのに『アップロード権限なし』が出ます。何が起きているのですか?
- ユーザーロールが正しい場合、次に疑うべきは REST API をブロックするセキュリティプラグインまたは WAF ルールです。Wordfence、iThemes Security、Solid Security、「Disable REST API」系プラグインにはいずれも、ブラウザ以外からの REST トラフィックを拒否する設定があります。Cloudflare WAF で
/wp-json/を対象としたルールも同じ効果を持ちます。ファイアウォールのイベントログで実際にブロックしているルールを特定し、そのルールだけを/wp-json/wp/v2/mediaに対して除外してください。 - WordPress の Application Password は、紐づくユーザーと同じロール権限を持ちますか?
- はい。Application Password はユーザーごとに発行され、認証されたリクエストはそのユーザーの capability そのままで実行されます。基となるユーザーが Subscriber であれば、Application Password が正常に発行されていてもアップロードはできません。Application Password には期限切れフィールドはなく、手動で revoke するまで有効です。
- ターミナルから
upload_filescapability を確認するには? - curl で
-u username:application-passwordを指定し、小さなテスト画像を/wp-json/wp/v2/mediaに POST します。HTTP 201 と新しいメディア ID を含む JSON が返ればアップロードは動作しています。HTTP 403 で code がrest_cannot_createならロールにupload_filesが不足。HTTP 401 でrest_invalid_authenticationなら Application Password が誤っているか revoke されています。WordPress 形式ではないレスポンスボディ(HTML エラーページや Cloudflare チャレンジ)で HTTP 403 が返る場合は、WordPress に届く前段のフィルタがブロックしています。 - いっそユーザーを Administrator に昇格させてはダメですか?
- 最後の手段として、かつ自分が完全に管理しているサイトでのみにしてください。最小権限の原則では、
upload_filesを持つ最小のロール、つまり Author を与えるべきです。Administrator は、設定・プラグイン・他ユーザーの管理が本当に必要なアカウントのために残しておきます。複数人で運用するサイトでは、upload_filesと最小限の投稿系 capability だけを持つ専用カスタムロールがさらに安全です。 - 何ヶ月も問題なく使えていたのに、突然アップロードできなくなりました。自分では何も変更していません。何が起きたのですか?
- 自分では何もしていないのに突然権限エラーが出るようになった場合、最も多い原因は、意図せず適用された緊急セキュリティアップデートです。WordPress コア自体のセキュリティリリース、またはセキュリティプラグインが自動配信するファイアウォールルール更新が該当します。これらのパッチは、脆弱性を塞ぐ過程で REST API や Application Password の挙動を副作用的に厳しくすることがあります。アップロードが動かなくなった日付と、WordPress のバージョンおよびセキュリティプラグインの更新履歴を照らし合わせてください。障害発生の前後1〜2日以内に更新が入っていれば、それが最有力候補です。
著者について
代表取締役 / 株式会社37Design
Web・AI顧問会社 株式会社37Design 代表取締役。WordPress管理のたびにiPhone写真を1枚ずつアップロードする手間に限界を感じてSnapPressを開発。
37design.co.jp