2026年8月4日
2026年8月4日
WordPressの「headers already sent」エラーの原因箇所を検出して修正する方法
「headers already sent」は、HTTPヘッダーを送る前に、何らかの文字がブラウザへ出力されてしまったことを示すエラーです。原因はたいてい1つのファイルの1行にあり、エラーメッセージの「output started at」にその場所が書かれています。この記事では、メッセージから原因箇所を読み取る方法、メッセージだけでは分かりにくいBOMや空白・警告文の検出方法、それぞれの直し方を説明します。
エラーメッセージの読み方
典型的なメッセージは次のような形です。
Warning: Cannot modify header information - headers already sent by (output started at /home/user/public_html/wp-content/themes/mytheme-child/functions.php:58) in /home/user/public_html/wp-includes/pluggable.php on line 1450
ファイルパスが2つ出てきますが、役割が違います。
- output started at ...:58:最初に文字を出力してしまった場所です。直すべきなのはこちらです。
- in ... pluggable.php on line ...:ヘッダーを送ろうとして失敗した場所です。リダイレクトやCookieの設定を行うWordPress本体の関数なので、ここを編集しても直りません(行番号はWordPressのバージョンによって変わります)。
PHPでは、ページ本文を1文字でも出力すると、その時点でヘッダーが確定して送信されます。その後でリダイレクトやCookieの設定をしようとすると、このエラーになります。
よく見られる症状
警告文が画面の上部に表示されるだけでなく、次のような症状として現れることがあります。
- ログイン画面でユーザー名とパスワードを入れても、ログイン画面に戻される
- 投稿の保存や設定の変更後に、真っ白な画面になる
- ブロックエディターで「更新に失敗しました」と表示され、応答が正しいJSONではないという趣旨のメッセージが出る
- RSSフィードを開くとXMLのエラーになる
ログインやリダイレクトはヘッダーで処理されるため、出力が先に起きるとそれらが動かなくなります。ブロックエディターやフィードでは、余計な文字が先頭に混ざることでデータとして読めなくなります。
エラーの記録を残す
画面に警告が出ていない場合や、ログイン処理の途中で消えてしまう場合は、ログに記録させます。wp-config.php を編集する前に、ファイルのコピーを取ってください。
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
これで wp-content/debug.log に「output started at」を含むメッセージが記録されます。サーバーのPHPエラーログにも同じ内容が残ることが多いです。
ここで WP_DEBUG_DISPLAY を false にしている点が大事です。画面にエラーを表示する設定のままだと、別の小さな警告(Deprecated や Warning)が画面に出力され、その表示自体がヘッダー送信前の出力になって、このエラーを引き起こすことがあります。本番サイトで警告を画面に出さないことは、それだけで対策の1つになります。
「output started at」の行を確認する
ログに出たファイルを開き、指定された行を確認します。原因はおおむね次のどれかです。
PHP開始タグの前にある空白や改行
ファイルの1行目が <?php で始まっておらず、その前に空行やスペースがあるケースです。行番号が :1 になっていることが多く、wp-config.php や functions.php を編集したあとによく起きます。
ファイル末尾の閉じタグの後ろにある改行
PHPだけで書かれたファイルの最後に ?> があり、その後ろに改行や空白が残っているケースです。行番号はファイルの最終行付近を指します。WordPressのコーディング規約でも、PHPだけのファイルでは末尾の ?> を省略することが推奨されており、省略すればこの問題は起きません。
直接の echo や HTML
functions.php の中で、フックを使わずに echo を書いていたり、関数の外にHTMLを書いていたりするケースです。動作確認のために入れた var_dump() や print_r() の消し忘れもここに含まれます。
別の警告メッセージ
「output started at」が wp-includes などの本体ファイルや、プラグインの別の行を指している場合、そこで出力されたのは別の警告文であることが多いです。debug.log で、このエラーの直前に記録されている Warning や Deprecated を確認してください。その警告を解消すれば、headers already sent も消えます。
メッセージから分かりにくい原因を検出する
BOM(バイトオーダーマーク)を探す
行番号が :1 で、開いてみても空白が見当たらない場合は、BOMが疑われます。BOMは「UTF-8 BOM付き」で保存したときにファイル先頭に付く見えない3バイトの印で、PHPはこれを出力として扱います。Windowsのメモ帳などで wp-config.php や functions.php を編集したときに付くことがあります。
SSHが使える場合は、次のコマンドで先頭にBOMがあるPHPファイルを一覧できます。
LC_ALL=C grep -rl --include='*.php' $'^\xEF\xBB\xBF' wp-content/ wp-config.php
SSHが使えない場合は、FTPで該当ファイルをダウンロードし、VS Code などのエディタで開きます。画面下部の文字コード表示が「UTF-8 with BOM」になっていればBOM付きです。
末尾の余分な文字を確かめる
ファイル末尾の ?> の後ろに何が残っているかは、エディタで見ても分かりにくいことがあります。SSHでは次のコマンドで、ファイルの最後の数十バイトを記号付きで表示できます。
tail -c 40 wp-content/themes/mytheme-child/functions.php | od -c
? > の後ろに \n や空白が複数並んでいれば、それが余分な出力です。
プラグインかテーマかを切り分ける
「output started at」のパスがプラグインの中を指している場合でも、そのプラグインの不具合なのか、他との組み合わせで起きているのかは分かりません。管理画面に入れるなら、Health Check & Troubleshooting プラグインのトラブルシューティングモードで、該当プラグインだけを有効にした状態を試します。管理画面に入れなければ、FTPでプラグインのフォルダ名を一時的に変えて止めます。
原因別の修正方法
修正前に、編集するファイルのバックアップを手元に保存してください。
- 開始タグ前の空白・末尾の改行:空白を削除し、PHPだけのファイルなら末尾の
?>ごと削除します。 - BOM:エディタで文字コードを「UTF-8」(BOMなし)に変えて保存し直し、サーバーへアップロードします。
- 直接の echo:出力は
wp_headやwp_footerなどのフック、またはテンプレート内に移します。ショートコードではechoではなく文字列をreturnします。 - リダイレクトのタイミング:テンプレートやショートコードの中で
wp_redirect()を呼んでいると、すでにページの出力が始まっているため失敗します。template_redirectフックなど、出力前のタイミングで処理します。
add_action( 'template_redirect', 'mysite_redirect_old_page' );
function mysite_redirect_old_page() {
if ( is_page( 'old-page' ) ) {
wp_safe_redirect( home_url( '/new-page/' ), 301 );
exit;
}
}
wp_safe_redirect() の後には exit を書き、後続の処理で出力が起きないようにします。
- プラグインが原因:最新版に更新し、直らなければ作者に「output started at」の行を添えて報告します。プラグインのファイルを直接直しても、更新で元に戻ります。
出力バッファリング(ob_start())でエラーを隠す方法もありますが、原因の出力が残ったままになり、別の場所で不具合を起こすことがあるため、おすすめしません。
修正後の確認
ログインとログアウト、投稿の保存、エラーが出ていたページの表示を試し、debug.log に新しいエラーが追記されないことを確認します。確認が終わったら、本番サイトでは WP_DEBUG を false に戻してください(WordPress本体の挙動は2026年10月現在のバージョンに基づいています)。
まとめ
- 「headers already sent」はヘッダー送信前に出力が起きたことを示し、直すべき場所は「output started at」に書かれたファイルと行です。
- 原因は、開始タグ前の空白、末尾
?>後の改行、BOM、直接の echo、画面に表示された別の警告が中心です。 WP_DEBUG_LOGでログを残し、grepやodでBOMや末尾の文字を検出し、エディタで文字コードを確認します。- 空白やBOMを取り除き、出力やリダイレクトを正しいフックに移して直します。編集前にはファイルのバックアップを取ります。