2026年5月21日
2026年5月21日
WordPressのREST APIが500エラーを返すときの調査手順と直し方
REST API(/wp-json/ 以下のURL)が500を返すとき、原因の大半は「そのリクエストを処理している途中でPHPが致命的エラーを起こしている」ことです。まずレスポンス本文とPHPのエラーログを見て、どのプラグイン・テーマのどの行で止まっているかを特定すれば、対処はほぼ決まります。この記事では、症状の確認からログの読み方、競合の切り分け、よくある原因ごとの直し方までを順番に説明します。
症状の出方を確認する
REST APIの500は、画面上では別の形で現れることが多いです。代表的なのは次のようなケースです。
- ブロックエディターで保存すると「更新に失敗しました。返答が正しい JSON レスポンスではありません。」のような通知が出る
- 管理画面の「ツール」→「サイトヘルス」で、REST APIに関する問題が報告される
- ヘッドレス構成やアプリ連携で、
/wp-json/wp/v2/postsなどの取得が失敗する - 一部のプラグイン画面(設定保存や一覧表示)だけが読み込み中のまま止まる
エディターの通知は「サーバーからJSON以外の何かが返ってきた」ことしか示しておらず、500以外(403や、PHPの警告文が混ざった200)でも同じ表示になります。そのため、最初にHTTPステータスと本文を自分の目で確かめることが近道です。
ステップ1:ステータスとレスポンス本文を見る
ブラウザの開発者ツールで確認する
管理画面でエラーが出る操作をする前に、ブラウザの開発者ツール(Chrome・Edgeなら F12)を開き、「Network(ネットワーク)」タブを表示しておきます。フィルター欄に wp-json と入力するか、種類を Fetch/XHR に絞ってから操作を行うと、失敗したリクエストが赤く表示されます。
そのリクエストを選び、「Headers」でステータスコードとURL、「Response」で本文を見ます。WordPressの致命的エラー処理が働いている場合、本文は次のようなJSONになっていることがあります。
{
"code": "internal_server_error",
"message": "<p>このウェブサイトに重大なエラーが発生しました。</p>...",
"data": { "status": 500 }
}
この形なら「PHPの致命的エラー」が確定で、次のステップのログ確認に進みます。本文が空、またはサーバーの汎用エラーページ(HTML)なら、PHPが起動する前のWebサーバー層(.htaccess、WAF、PHP-FPMの異常など)を疑います。
URLを直接たたいて範囲を絞る
ブラウザやターミナルから、いくつかのエンドポイントを直接開いて、失敗する範囲を調べます。
curl -i https://example.com/wp-json/
curl -i https://example.com/wp-json/wp/v2/posts
curl -i "https://example.com/?rest_route=/wp/v2/posts"
/wp-json/(インデックス)から500なら、REST APIの初期化時に読み込まれる処理全体に問題があります。特定のルートだけ500なら、そのルートを登録しているプラグインやカスタムエンドポイントのコールバックが原因と見当がつきます。?rest_route= 形式だけ通る場合は、パーマリンクや書き換えルール側の問題です。
ステップ2:PHPのエラーログで原因の行を特定する
作業前に、wp-config.php を含むファイル一式とデータベースのバックアップを取っておきます。そのうえで wp-config.php の /* That's all, stop editing! */ より上に次を追記します。
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );
WP_DEBUG_DISPLAY を false にするのが大事な点です。画面にエラーを表示すると、その文字列がJSONの前に混ざり、500とは別の「JSONが不正」というエラーを新たに作ってしまいます。
再度エラーを起こすと、wp-content/debug.log に記録が残ります。探すのは PHP Fatal error や Uncaught Error で始まる行です。たとえば Allowed memory size of ... bytes exhausted ならメモリ不足、Call to undefined function や Class "..." not found なら読み込み順や依存関係の問題、TypeError ならPHPバージョンとの非互換が疑われます。行末のファイルパスに wp-content/plugins/プラグイン名/ が含まれていれば、そのプラグインが第一候補です。
debug.log に何も出ない場合は、レンタルサーバーのコントロールパネルにある「エラーログ」や、Apache・Nginx・PHP-FPMのログを確認します。WordPressが読み込まれる前に止まっていると、debug.log には記録されません。
調査が終わったら、WP_DEBUG は false に戻し、debug.log は削除するか外部から見えない場所に移します。ログにはファイルパスなどの内部情報が含まれるためです。
ステップ3:プラグイン・テーマの競合を切り分ける
ログで犯人が特定できない場合や、複数のプラグインが絡んでいそうな場合は、競合の切り分けを行います。本番サイトで訪問者に影響を出さずに行うなら、プラグイン「Health Check & Troubleshooting」のトラブルシューティングモードが便利です。このモードはログイン中の自分のセッションだけで、すべてのプラグインを無効にし、デフォルトテーマに切り替えた状態を作れます。訪問者には通常どおりのサイトが表示されます。
トラブルシューティングモードで500が消えたら、プラグインを1つずつ有効にして再発するものを探します。テーマを戻したときに再発するなら、テーマの functions.php などが原因です。
WP-CLIが使える環境なら、Webサーバーを経由せずにREST APIを内部から呼び出して比較できます。
wp eval 'echo rest_do_request( "/wp/v2/posts" )->get_status() . PHP_EOL;'
wp --skip-plugins --skip-themes eval 'echo rest_do_request( "/wp/v2/posts" )->get_status() . PHP_EOL;'
1行目で500相当のエラーが出て2行目で200が返るなら、プラグインかテーマが原因です。どちらも200なのにブラウザからは500になる場合は、WordPressの外側(.htaccess、WAF、PHP-FPMの設定)を調べます。
よくある原因と直し方
カスタムエンドポイントのコールバックのエラー
自作やテーマ同梱の register_rest_route() で登録したエンドポイントだけが500になるケースです。コールバック内で未定義の変数や関数を呼んでいる、permission_callback の関数名を間違えている、などがよくある原因です。エラーを返したいときは例外で止めるのではなく、WP_Error に適切なステータスを付けて返すと、クライアント側で原因が読みやすくなります。
add_action( 'rest_api_init', function () {
register_rest_route( 'myplugin/v1', '/item/(?P<id>\d+)', array(
'methods' => 'GET',
'callback' => 'myplugin_get_item',
'permission_callback' => function () {
return current_user_can( 'read' );
},
) );
} );
function myplugin_get_item( WP_REST_Request $request ) {
$post = get_post( (int) $request['id'] );
if ( ! $post ) {
return new WP_Error( 'not_found', '指定の投稿がありません。', array( 'status' => 404 ) );
}
return rest_ensure_response( array(
'id' => $post->ID,
'title' => get_the_title( $post ),
) );
}
メモリ不足
投稿一覧の取得で大量のメタデータを読み込む処理などが重なると、PHPのメモリ上限に達して500になります。ログにメモリ枯渇のメッセージがある場合は、wp-config.php で define( 'WP_MEMORY_LIMIT', '256M' ); を設定します。ただしサーバー側の memory_limit がそれより低いと効かないため、サーバーのPHP設定画面も確認します。根本的には、一度に取得する件数(per_page)を減らす、重い処理をしているプラグインを見直すほうが効果があります。
PHPバージョンとの非互換
サーバーのPHPを上げた直後から500が出るようになった場合、古いプラグインが新しいPHPで削除された関数や書き方を使っている可能性があります。ログの TypeError や Deprecated の直後の Fatal error が手がかりです。プラグインを最新版に更新し、それでも直らなければ代替プラグインを探すか、一時的にPHPのバージョンを戻して時間を稼ぎます。
.htaccessやサーバー層の問題
本文がサーバーの汎用エラーページで、debug.log にも記録が無い場合は、.htaccess の記述ミスやWAFによるブロックの可能性があります。.htaccess をバックアップしてから、管理画面の「設定」→「パーマリンク」で何も変えずに「変更を保存」を押すと、WordPress標準の書き換えルールが書き直されます。WAFが原因の場合は、サーバーのコントロールパネルでWAFのログを確認し、該当するリクエストを除外する設定を検討します。
直ったあとの確認
修正後は、ステップ1と同じURLで200が返ること、ブロックエディターで下書き保存と公開ができること、「サイトヘルス」でREST APIの問題が消えていることを確認します。キャッシュ系プラグインやCDNを使っている場合は、古いエラー応答が残っていることがあるので、キャッシュを削除してから確認してください。WordPressのバージョンによってサイトヘルスの表記は変わることがあります(2026年10月現在)。
まとめ
- REST APIの500は、多くがリクエスト処理中のPHP致命的エラー。最初に開発者ツールのNetworkタブで、ステータスと本文を確認する
WP_DEBUG_LOGを有効、WP_DEBUG_DISPLAYを無効にして debug.log の Fatal error を探し、原因のファイルと行を特定する- 特定できなければ Health Check & Troubleshooting や WP-CLI の
--skip-pluginsで競合を切り分ける - カスタムエンドポイントは
WP_Errorに適切なステータスを付けて返し、permission_callbackを正しく設定する - 作業前のバックアップと、調査後の WP_DEBUG の無効化を忘れない