LuxeritasでreCAPTCHA v3が接続失敗(HTTP 418)になる原因と解決策
2026年6月の時点では正常に動作していた当ブログのコメント欄ですが、ふと気づくとコメントが全くつかない状態が続いていました。不審に思ってコメント欄を確認したところ、これまでスパム対策として運用していた「SiteGuard WP Plugin」のひらがな画像認証が表示エラーを起こしており、読者がコメントを投稿できない状態に陥っていました。
SiteGuardの画像認証は日本語話者以外のスパムを弾くのに有効でしたが、コメントを投稿するたびに読者へ文字入力を強いるため、利便性の観点では課題がありました。そこで今回の障害復旧を機に、手動入力を必要とする画像認証を廃止し、バックグラウンドで挙動をスコアリングする「Google reCAPTCHA v3」へ移行してコメント欄を刷新することにしました。
入力負担の削減とスパム排除の両立
reCAPTCHA v3の導入にあたり、コメント欄のフォーム設計そのものも見直すことにしました。WordPressの標準コメント欄に存在する「メールアドレス」や「ウェブサイトURL」の入力欄は、一般的な個人ブログへの感想投稿においては心理的ハードルになります。
そこで、フォームの項目を「名前」と「本文」の2点のみに絞り込み、入力順序も「名前 → 本文」の順へ再編成することを目指しました。
運用の目標は以下の通りです。
- 読者の入力負荷をゼロにする(画像選択や文字入力を廃止し、入力必須項目を名前と本文のみに削減)。
WordPressの「設定」→「ディスカッション」やLuxeritasのテーマ標準機能には、特定の入力欄を完全に削除したり項目の並び順を入れ替えたりする設定項目が存在しないため、自作のプラグイン(mu-plugins)によるフィルターフックでレイアウトを制御することにしました。
投稿を阻む「認証サーバーへの接続に失敗しました」とHTTP 418
Google reCAPTCHAの管理画面でv3のサイトキーとシークレットキーを発行し、Luxeritasの外観カスタマイズ画面から各キーを登録して設定を保存しました。
設定完了後、動作確認のためにブラウザからテストコメントを送信したところ、次のエラーメッセージが表示されて処理が中断されました。
Google reCAPTCHA : 認証サーバーへの接続に失敗しました。 しばらくしてからもう一度お試しください。
「接続に失敗しました」という文面から、WebサーバからGoogleのAPIエンドポイントへの通信遮断を疑い、ブラウザの開発ツール(F12)でネットワーク通信を確認しました。すると、POST先である wp-comments-post.php から返されていたHTTPステータスコードは、見慣れない「418 I’m a teapot」でした。
外部APIとのネットワーク通信エラーなのか、サーバやプロキシの設定不良なのか、それともテーマのバグなのか、エラー画面のメッセージだけでは判別がつかない状況に直面しました。
サーバ疎通テストとLuxeritas内部コードの解析
まずはエラー文面通り「認証サーバへの接続」が失敗しているのかを切り分けるため、WordPressを稼働させているDockerコンテナ内部からGoogleの認証APIへ疎通確認を行いました。
curl -Iv https://www.google.com/recaptcha/api/siteverify
コンテナ内からのcURLコマンドは即座にDNS名前解決を行い、SSLハンドシェイクを通過して HTTP/2 200 を返しました。さらに、WordPressのHTTPリクエスト関数を経由した場合の挙動をCLIからテストしました。
php -r 'require "wp-load.php"; $res = wp_remote_post("https://www.google.com/recaptcha/api/siteverify"); var_dump($res);'
この実行結果でも HTTP/1.1 200 OK が返り、レスポンスボディには Google API からの応答として invalid-input-response(トークン未指定による正常なエラー応答)が格納されていました。これにより、OS・コンテナ・PHP・cURL・SSL証明書を含むインフラ層の通信は完全に健全であり、外部通信の遮断が原因ではないことが確定しました。続いて、Luxeritasのテーマファイル内でエラーメッセージを検索し、処理ロジックを直接確認しました。
grep -rn "Connection to the authentication server failed" wp-content/themes/luxeritas/
該当箇所である wp-content/themes/luxeritas/functions.php のコメント処理フックを確認したところ、決定的なコードが見つかりました。
if( isset( $_POST['g-recaptcha-response'] ) ) {
$verify = 'https://www.google.com/recaptcha/api/siteverify?secret=' . $luxe['recaptcha_secret_key'] . '&response=' . $_POST['g-recaptcha-response'];
$ret = thk_remote_request( $verify );
...
if( !isset( $json->success ) || ( isset( $json->success ) && $json->success !== true ) ) {
wp_die( $msg1, '', array( 'response' => 418, 'back_link' => true ) );
}
...
}
else {
wp_die( $msg1, '', array( 'response' => 418, 'back_link' => true ) );
}
このコードから2つの事実が判明しました。ステータスコード 418 の正体は、Luxeritasがコメント処理を中断する際に意図して wp_die() に渡している独自仕様であったこと。変数 $msg1(「認証サーバーへの接続に失敗しました」)は、実際の通信エラー時だけでなく、$_POST['g-recaptcha-response’] が存在しない場合の else 句でも共通して出力される仕様であったこと。つまり、実際にはGoogleのサーバへ接続して失敗したのではなく、「ブラウザからトークンが送信されてこなかったため即座に418で弾かれていた」というのがエラーの真相でした。
Form Dataの欠落と自作プラグインによるフィールド破壊の特定
ブラウザの開発ツールの「ネットワーク」タブを開き、送信されたPOSTリクエスト(wp-comments-post.php)のPayload(Form Data)を確認しました。
author=%E3%81%A6&comment=%E3%81%82%E3%81%82%E3%81%82&submit=%E3%82%B3%E3%83%A1%E3%83%B3%E3%83%88%E3%82%92%E9%80%81%E4%BF%A1&comment_post_ID=5563&comment_parent=0
送信データの中に、reCAPTCHAの認証トークンである g-recaptcha-response が一切含まれていませんでした。
なぜフロントエンドからトークンが送られてこないのか調査を進めた結果、以前に自分で作成して配置していた自作mu-plugin(wp-content/mu-plugins/comment-form-layout.php)に行き当たりました。
</pre>
add_filter( 'comment_form_fields', function( $fields ) {
// 不要な項目を削除
unset( $fields['email'], $fields['url'] );
$new_fields = array();
// 名前欄を先頭に配置
if ( isset( $fields['author'] ) ) {
$new_fields['author'] = $fields['author'];
}
// コメント欄を配置
if ( isset( $fields['comment'] ) ) {
$new_fields['comment'] = $fields['comment'];
}
return $new_fields;
} );
<pre>
不具合の元凶はこのコードでした。WordPressの comment_form_fields フィルターフックは、フォーム内に出力されるすべての要素(名前、メール、本文のほか、テーマやプラグインが挿入するhiddenフィールドやスクリプト用マークアップ)が連想配列として渡されます。
上記のコードでは、空の配列 $new_fields を新しく作成し、author と comment だけを詰めて返していました。その結果、LuxeritasがreCAPTCHA v3の制御やトークン受け渡しのためにフォーム内へ出力していた構成要素を、メール欄やURL欄と一緒に丸ごと破棄してしまっていたのです。
「画面上で名前と本文の並び順が変わり、正しく表示されているから問題ない」と思い込んでいた過去の拙いコードが、別の機能(reCAPTCHA)を追加した際に致命的な不具合を引き起こしていました。WordPressのフィルターフックは他のプラグインやテーマとも共有するパイプラインであるという意識が欠けていた点について、大いに反省させられました。
array_mergeによる安全なフック実装への修正と復旧
原因が自作プラグインによる配列の上書き破壊であると特定できたため、コードの修正を行いました。他のテーマ機能やプラグインが追加した未知のフィールドを破棄せず、安全に末尾へ残すように実装を改めました。
wp-content/mu-plugins/comment-form-layout.php を以下のコードへ書き換えます。
<?php
/**
* Plugin Name: Nando Comment Form Custom Layout
* Description: コメント欄を「名前 → 本文」の順に変更し、不要な項目(メール・URL)を削除します。
* Version: 1.0.1
* Author: 納戸工房
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
add_filter( 'comment_form_fields', function( $fields ) {
// 不要な項目(メール・サイトURL)を削除
unset( $fields['email'], $fields['url'] );
// コメント本文欄を一度退避して配列から削除
$comment_field = '';
if ( isset( $fields['comment'] ) ) {
$comment_field = $fields['comment'];
unset( $fields['comment'] );
}
$new_fields = array();
// 1. 名前欄を先頭に配置
if ( isset( $fields['author'] ) ) {
$new_fields['author'] = $fields['author'];
unset( $fields['author'] );
}
// 2. 本文欄を2番目に配置
if ( ! empty( $comment_field ) ) {
$new_fields['comment'] = $comment_field;
}
// 3. テーマや他プラグインが追加した残りのフィールドを末尾に保持して結合
return array_merge( $new_fields, $fields );
} );
修正の要点は、配列の再構成後に array_merge( $new_fields, $fields ) を行っている点です。元の $fields 配列から明示的に unset していない要素(テーマや他プラグインがフック経由で差し込んだhiddenフィールドや制御用マークアップ)を破棄せず、すべて末尾に保持してWordPressコアへ返却します。
コードの修正完了後、LiteSpeed Cacheの管理画面から「すべてのキャッシュをパージ」を実行し、古いHTMLキャッシュをクリアしました。
その後、ブラウザのシークレットウィンドウから該当記事のコメント欄を開き、テストコメントの送信を行いました。
送信ボタンを押した直後、エラー画面(HTTP 418)を挟むことなく、投稿されたコメントが即座に画面へ反映されました。ブラウザの開発ツールで送信されたリクエスト(wp-comments-post.php)のPayload(Form Data)を再確認したところ、以前は欠落していた g-recaptcha-response に長い英数字のトークンが正常に格納されていました。
なお、reCAPTCHA v3は従来のv2のように画像選択や「私はロボットではありません」のチェックボックスを表示せず、バックグラウンドでユーザーの挙動を解析して0.0〜1.0のスコアで自動判定する仕様です。そのため、正常に認証を通過した場合は何のエラーもUI変化も起きず、そのままコメントが投稿されます。本当に稼働しているか確認したい場合は、Google reCAPTCHAの管理コンソールを開き、直近のリクエスト数グラフとスコア分布(人間として高スコアで判定されているか)を確認することで客観的な動作ログを把握できます。
まとめ
SiteGuardの画像認証エラーを機にreCAPTCHA v3へ移行した際、「認証サーバーへの接続に失敗しました(HTTP 418)」が発生しました。サーバ疎通テストとテーマ解析の結果、通信障害ではなくトークンの送信漏れが原因と判明しました。真因はコメント欄整理用の自作フックがreCAPTCHA要素を巻き添え削除していた点にありました。array_mergeを用いて既存要素を保持する安全なコードへ修正したことで、入力負担のない正常なコメント受付を復旧できました。フック処理では共有パイプラインを壊さない設計が不可欠です。

