2026年7月11日

2026年7月11日

WordPressのパーミッションエラーを直す方法|ファイル権限と管理画面の「権限がありません」

WordPressの「パーミッションエラー」は、ファイルの書き込み権限が足りない場合と、ユーザーの権限(ロール)情報が壊れている場合の2系統に分かれます。前者は所有者とパーミッションを正しい組み合わせに戻せば直り、777にする必要はありません。この記事では、エラーの種類を見分け、PHPがどのユーザーで動いているかを確かめたうえで、安全な権限に戻す手順を説明します。

まずエラーの種類を見分ける

同じ「権限」という言葉でも、原因の場所が異なります。表示されている内容で切り分けてください。

ファイル権限の問題(サーバー側)

  • 画像のアップロード時に、アップロードしたファイルを wp-content/uploads/… へ移動できなかった、という趣旨のエラーが出る
  • 「ディレクトリを作成できませんでした。親ディレクトリに書き込み権限がありますか?」という趣旨のエラーが出る
  • プラグインやテーマの更新時に、FTPの接続情報を求める画面が出る
  • 更新が「Could not create directory」で失敗する
  • ページ全体が403 Forbiddenになる

ユーザー権限の問題(データベース側)

  • 管理者でログインしているのに「Sorry, you are not allowed to access this page.」(日本語環境では「このページにアクセスする権限がありません」という趣旨の表示)が出る
  • サイトの移転やテーブル接頭辞の変更の直後から、管理画面のメニューがほとんど表示されない

前者はこの記事の前半、後者は後半の手順で対処します。

PHPを実行しているユーザーを確認する

ファイル権限の問題は、「WordPressのファイルの所有者」と「PHPを実行しているユーザー」が食い違っていることが多くの原因です。最初にこの2つを確認します。

# PHPの実行ユーザー(php-fpmはmasterがroot、workerがプールのユーザー)
ps -eo user,comm | grep -E 'php-fpm|apache2|httpd' | sort | uniq -c

# WordPressのファイルの所有者とパーミッション
ls -ld /var/www/html /var/www/html/wp-content /var/www/html/wp-content/uploads

php-fpmを使っている場合、rootで動いているのはmasterプロセスだけで、実際にPHPを処理するのはworkerプロセスです。workerのユーザーが、書き込みたいディレクトリに書き込めるかどうかが判断の基準になります。2026年10月時点で、Debian/Ubuntuのパッケージの既定は www-data、RHEL系は apache(Nginxと組み合わせる場合は nginx に変えていることが多い)です。プールごとのユーザーは、Debian/Ubuntuなら /etc/php/バージョン/fpm/pool.d/*.conf、RHEL系なら /etc/php-fpm.d/*.conf の user = と group = で確認できます。

書き込めるかどうかは、そのユーザーになって実際に試すのが早い方法です。

sudo -u www-data touch /var/www/html/wp-content/uploads/perm-test.txt && echo OK
sudo rm -f /var/www/html/wp-content/uploads/perm-test.txt

# 途中のディレクトリも含めて権限を一覧表示
namei -l /var/www/html/wp-content/uploads

namei -l は、パスの途中にある各ディレクトリの所有者と権限を順に表示します。uploads自体は書き込み可能でも、上位のディレクトリに実行権(x)がないと中に入れません。見落としやすい箇所です。

推奨されるパーミッションと所有者の考え方

一般的な基準は「ディレクトリ755・ファイル644」です。ただし、この数字だけでは書き込めるかどうかは決まりません。誰が所有者で、PHPがどのユーザーで動くかとの組み合わせで決まります。代表的な構成は次の3つです。

構成A:PHPがサイト専用ユーザーで動く

多くのレンタルサーバーや、サイトごとにPHP-FPMのプールを分けたVPSの形です。ファイルの所有者とPHPの実行ユーザーが同じなので、755/644のままで書き込めます。もっとも扱いやすい構成です。

構成B:所有者は作業用ユーザー、PHPはwww-data

コードは作業用ユーザー(例: deploy)が所有し、書き込みが必要な wp-content/uploads などだけをグループ www-data に書き込み可能(775/664)にします。管理画面からのコア・プラグインの更新はできなくなりますが、PHPの脆弱性を突かれてもコードを書き換えられにくい構成です。

構成C:すべてをwww-dataが所有する

管理画面からの更新はすべて動きますが、PHPの脆弱性を突かれたときにすべてのファイルが書き換え可能になります。手軽な一方で、防御面では一番弱い形です。

どの構成でも、777にする必要はありません。777は所有者を合わせられないときの応急処置として紹介されることがありますが、同じサーバーの他のユーザーやプロセスからも書き換え可能になります。

権限を一括で戻すコマンド

作業前に、現在の状態を記録しておくと元に戻せます。getfacl -R の出力にはパーミッションのほか所有者とグループも含まれ、setfacl --restore で復元できます。

WP_ROOT=/var/www/html
cd "$WP_ROOT"

# 作業前の権限を保存(リダイレクトは自分の権限で行われるので、保存先は自分のホームにする)
sudo getfacl -R . > ~/wp-perms.acl
# 復元するときは同じディレクトリで: cd /var/www/html && sudo setfacl --restore="$HOME/wp-perms.acl"

構成Cの例です。所有者をPHPの実行ユーザーにそろえ、ディレクトリ755・ファイル644にします(構成Aでは、www-data の部分をサイト専用ユーザーに読み替えます)。

WP_ROOT=/var/www/html
sudo chown -R www-data:www-data "$WP_ROOT"

# ディレクトリ755、ファイル644
sudo find "$WP_ROOT" -type d -exec chmod 755 {} +
sudo find "$WP_ROOT" -type f -exec chmod 644 {} +

# wp-config.php は所有者だけが読み書きできるように
sudo chmod 600 "$WP_ROOT/wp-config.php"

構成Bの場合は、所有者を作業用ユーザーにし、書き込みが必要な場所だけグループ権限を付けます。

sudo chown -R deploy:www-data /var/www/html
sudo find /var/www/html -type d -exec chmod 755 {} +
sudo find /var/www/html -type f -exec chmod 644 {} +

# uploads だけグループ書き込み可。setgid で新規ファイルのグループも www-data に固定
sudo find /var/www/html/wp-content/uploads -type d -exec chmod 2775 {} +
sudo find /var/www/html/wp-content/uploads -type f -exec chmod 664 {} +

# 構成Bでは wp-config.php を 640 にしてグループ(PHP)に読ませる
sudo chmod 640 /var/www/html/wp-config.php

つまずきやすいのが wp-config.php です。600や400にすると、所有者以外は読めません。所有者が deploy でPHPが www-data の構成で600にすると、PHPが設定を読めずにサイト全体が表示されなくなります。所有者とPHPの実行ユーザーが違うなら640、同じなら600または400、と使い分けてください。

更新時にFTP情報を求められる場合

プラグインの更新でFTPの接続情報を求められるのは、WordPressが「PHPが新しく作ったファイルの所有者」と「WordPress自身のファイルの所有者」を比べ、一致しないと判断したためです。この場合、直接書き込むと所有者がばらばらになるため、FTP経由を求めてきます。

根本の対処は、構成AかCのように所有者をそろえることです。所有者がそろっていれば、追加の設定をしなくても直接更新されます。wp-config.php に次の定数を書けば直接書き込みを強制できますが、所有者が食い違ったまま使うと、更新されたファイルだけ所有者が変わり、後から別の権限エラーを生みます。

// 所有者をそろえたうえで、それでも判定がうまくいかない場合のみ
define( 'FS_METHOD', 'direct' );

構成Bのように意図的に書き込みを禁止している場合は、管理画面からは更新せず、WP-CLIを作業用ユーザーで実行して更新する運用にします。

SELinuxやディスク容量が原因のこともある

パーミッションと所有者が正しいのに書き込めない場合は、OS側の制限を疑います。

SELinux(RHEL・AlmaLinux・Rocky Linuxなど)

SELinuxが有効だと、Webサーバーが書き込めるのは書き込み用のラベルが付いたディレクトリだけです。ls -Z でラベルを確認し、uploadsに書き込み用のラベルを付けます。

ls -Zd /var/www/html/wp-content/uploads

# 恒久的なルールを登録してから適用
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/wp-content/uploads(/.*)?"
sudo restorecon -Rv /var/www/html/wp-content/uploads

chcon でも一時的にラベルを変えられますが、restorecon を実行すると元に戻るため、semanage fcontext での登録をおすすめします。

ディスク容量・inode

容量が尽きていても書き込みエラーになります。df -h と df -i の両方を確認してください。inodeが枯渇していると、容量に空きがあってもファイルを作れません。

管理画面で「権限がありません」と出る場合

管理者なのにアクセスを拒否される場合は、ファイルではなくデータベース上の権限情報を確認します。WordPressはロールの定義を {接頭辞}user_roles というオプションに、各ユーザーのロールを {接頭辞}capabilities というユーザーメタに保存しています。サイトの移転時にテーブル接頭辞を変えたのに、これらのキー名を書き換えていないと、WordPressはユーザーにロールがないと判断します。

作業前にデータベースのバックアップを取ってから、WP-CLIで確認します。

wp db export before-role-fix.sql

# wp-config.php の $table_prefix
wp db prefix

# ユーザーに付いているロール
wp user get admin --field=roles

# capabilities のメタキー名が接頭辞と一致しているか
wp db query "SELECT user_id, meta_key FROM $(wp db prefix)usermeta WHERE meta_key LIKE '%capabilities';"

メタキーが wp_capabilities なのに接頭辞が abc_ になっている、といった食い違いがあれば、メタキー名を新しい接頭辞に合わせて書き換えます。同様に、optionsテーブルの wp_user_roles も abc_user_roles に直します。

# 例: 旧接頭辞 wp_ → 新接頭辞 abc_ の場合
wp db query "UPDATE abc_usermeta SET meta_key = REPLACE(meta_key, 'wp_', 'abc_') WHERE meta_key IN ('wp_capabilities', 'wp_user_level');"
wp db query "UPDATE abc_options SET option_name = 'abc_user_roles' WHERE option_name = 'wp_user_roles';"

ロールの定義そのものが壊れている場合は、既定のロールに戻すコマンドが使えます。

# administrator ロールの権限を初期状態に戻す
wp role reset administrator

# 特定ユーザーに管理者ロールを付け直す
wp user set-role admin administrator

権限管理系のプラグインでロールを編集していた場合、wp role reset でその変更も初期化されます。実行前に wp role list と wp cap list administrator の出力を保存しておくと、後で比較できます。

直ったことを確認する

作業後は次の順で確認します。

  • メディアから画像を1枚アップロードし、サムネイルも生成されるか
  • プラグインを1つ更新し、FTP情報を求められないか(構成Bでは管理画面から更新しない運用なので対象外)
  • 「ツール」→「サイトヘルス」の「情報」タブで、ファイルシステムの権限の項目に書き込み不可のディレクトリがないか
  • ls -l で、更新後に作られたファイルの所有者が他のファイルとそろっているか

最後の確認は見落とされがちですが、所有者のずれが残っていると次の更新で同じエラーが再発します。

まとめ

  • パーミッションエラーは「ファイル権限」と「ユーザーのロール情報」の2系統。表示されるメッセージで切り分ける
  • ファイル権限は、PHPの実行ユーザーとファイルの所有者の組み合わせで決まる。sudo -u www-data touch で実際に書き込めるかを試す
  • 基準はディレクトリ755・ファイル644。777は使わず、所有者をそろえるか、書き込みが必要な場所だけグループ権限を付ける
  • wp-config.php は、所有者とPHPの実行ユーザーが同じなら600、違うなら640
  • FTP情報を求められるのは所有者のずれが原因。FS_METHOD は所有者をそろえたうえでの補助手段
  • 正しい権限でも書き込めないときは、SELinuxのラベルとディスク容量・inodeを確認する
  • 管理画面の「権限がありません」は、テーブル接頭辞とメタキー名の食い違いを最初に疑う

関連記事:

お気軽にご相談ください

お見積りへ お問い合わせへ
▲