速度改善・安全対策

WordPressで412 Precondition Failedが出るときの直し方|ETag・更新条件の安全な確認順

WordPressの記事保存、REST API、外部同期、キャッシュ連携で「412 Precondition Failed」が返ることがあります。要求の形式は正しくても、「この版のままなら更新する」と指定した前提条件が、現在のサーバー状態と一致しない場合です。

412では、エラーを消すためにIf-Match等を削除するのではなく、自分の編集内容を退避し、対象の最新状態と新しいETag・更新日時を取得します。そのうえで差分を統合し、APIの仕様に沿った条件で再送します。

条件ヘッダーを外して強制上書きしたり、古い画面から保存を連打したりしないでください。412は、別の変更を誤って消す「更新消失」を防ぐために処理を止めている場合があります。

先に結論:412エラーは8段階で確認する

  1. 編集中の本文や入力値を別の安全な場所へ退避する
  2. 保存・同期の連打と自動再試行を止める
  3. 操作、時刻、URL、HTTPメソッド、対象ID、412を記録する
  4. If-Match、If-None-Match、If-Unmodified-Sinceの有無を確認する
  5. 前回の処理がすでに成功していないか調べる
  6. 対象の最新内容、ETag、Last-Modified等を正規の方法で取得する
  7. 送信版と現在版の差分を統合し、新しい条件で一度だけ再送する
  8. 保存結果、リビジョン、外部同期、重複処理の有無まで確認する

条件ヘッダーではなく、対象の現在状態と一般的に競合している場合はWordPressの409 Conflictを直す確認順、入力値の必須・型・範囲が問題ならWordPressの422 Unprocessable Contentを直す確認順へ切り替えます。

412 Precondition Failedとは?

RFC 9110の412 Precondition Failedは、要求ヘッダーで指定した一つ以上の条件をサーバーが評価した結果、偽になった状態です。対象が想定外の状態なら、要求した処理を適用しないために使われます。

代表例は、対象を取得したときのETagをIf-Matchで更新要求へ付けたものの、保存前にサーバー上の版が変わっていた場合です。サーバーは古い版を基にした上書きを止め、利用者へ最新状態の再確認を促せます。

WordPress本体の通常の投稿更新が、常にIf-Matchと412を使うわけではありません。プラグインの独自REST API、外部ストレージ、EC・会員・同期サービス、CDNやAPIゲートウェイが条件付き要求を採用している場合もあります。まず実際の要求先と応答本文を確認してください。

WordPressに同梱されるHTTPクライアントは外部サービスからの412を識別できますが、それはWordPressの標準投稿保存が必ず412を生成するという意味ではありません。番号だけで機能やプラグインを断定しないことが大切です。

古い版の検証キーが現在状態の保管庫ロックと一致せず停止する設備

304・409・412・428の違い

表示主な意味最初に見るもの
304 Not ModifiedGET・HEADのキャッシュ検証で未変更If-None-Match、If-Modified-Since、キャッシュ
409 Conflict要求が対象の現在状態と競合する同時更新、重複、状態遷移、同期
412 Precondition Failed要求ヘッダーで指定した条件が偽If-Match、If-None-Match、If-Unmodified-Since
428 Precondition Requiredサーバーが条件付き要求を必須としている必要な条件ヘッダーと取得手順

If-None-Matchの条件が偽の場合、GETまたはHEADでは304、その他のメソッドでは412になります。「同じETagなのに番号が違う」ときは、HTTPメソッドと処理目的を確認してください。

428は「条件を付けてください」、412は「付けた条件が現在状態では成立しません」という違いです。どちらも条件ヘッダーを邪魔なものとして削るのではなく、APIが求める取得・更新手順を確認します。

JSONやURL自体が正しく解釈されていないならWordPressの400 Bad Requestを直す確認順、対象ルートがそのHTTPメソッドを受け付けないならWordPressの405 Method Not Allowedを直す確認順が適切です。

WordPressで412が出る主な原因

1.古いETagをIf-Matchで送っている

記事や外部データを取得した後、別の担当者、別タブ、自動処理、同期サービスが先に更新すると、現在版のETagが変わります。古いETagをIf-Matchへ入れた更新は、意図しない上書きを防ぐため拒否されます。

ETagは画面に見える版番号とは限らず、引用符を含む文字列です。値から引用符を外す、弱いETagのW/を削る、似た値へ書き換えると条件の意味が変わります。応答で受け取った値をAPI仕様どおりに扱います。

2.If-Unmodified-Sinceの日時より後に更新された

If-Unmodified-Sinceは、指定日時以降に対象が変更されていない場合だけ処理する条件です。画面を開いてから保存するまでに対象が更新された、サーバーとクライアントの時刻や形式がずれた、古いLast-Modifiedを再利用した場合に失敗します。

ローカル端末の現在時刻を推測で入れず、対象を取得した応答のLast-ModifiedとAPI仕様を使います。If-Matchも同時にある場合、RFCではIf-Matchがより正確な条件として優先され、If-Unmodified-Sinceは無視されます。

3.If-None-Matchで「未作成」を条件にしたが既に存在する

If-None-Match: *は、対象に現在の表現がない場合だけ作成したいときに使えます。前回の作成がすでに成功している、別処理が同じIDを先に作成した、応答を受け取れず再送した場合は条件が成立しません。

新しいIDやキーへ変えて回避する前に、既存対象が同じ処理の結果かを確認します。注文、決済、会員、通知では、無理に別物として作成すると重複につながります。

4.キャッシュやオフラインキューが古い条件を保持している

ブラウザ、編集アプリ、Service Worker、モバイルアプリ、連携ツールが、取得時のETagや更新日時を保存したまま送ることがあります。バックアップ復元、サイト移行、長時間のオフライン後に、古いキューが再送されるケースもあります。

キャッシュ全削除だけで終わらせず、どのクライアントが条件を保存し、いつ再取得する設計かを確認します。古い処理キューは、内容と前回結果を確認してから破棄または再作成します。

5.プラグインや外部APIの条件付き更新仕様が変わった

API更新でIf-Matchが必須になった、ETagの形式が変わった、弱い検証子を受け付けなくなった、取得先と更新先のAPI版がずれた場合があります。連携プラグイン更新直後なら、変更履歴と公式の要求例を確認します。

412を返したのがWordPressのURLでも、ルートを登録したのはプラグインかもしれません。RESTルート、名前空間、外部ドメイン、応答のエラーコードから担当範囲を特定します。

プラグインや連携方法を変更する前に、WordPress更新前のバックアップ手順で戻せる状態を用意し、WordPressのテスト環境を作る手順に沿って本番と分けて検証してください。

6.前回処理は成功したが、応答だけ失われた

更新要求がサーバーで完了した後、通信切断やタイムアウトで成功応答を受け取れず、古いETagのまま再送すると412になることがあります。この場合、サーバー上の内容はすでに目的の状態かもしれません。

再送前に現在状態を取得し、目的の変更が反映済みか確認します。RFCは、状態変更がすでに適用されたと判断できる場合、サーバーが成功応答を返し得ることも説明していますが、実装ごとに異なります。

最初の10分で行う安全な初動

1.編集内容と条件情報を別々に退避する

本文、商品情報、フォーム入力を安全な場所へコピーします。調査メモには、時刻、URL、メソッド、対象ID、412、リクエストID、使用した条件ヘッダー名を記録します。認証トークン、Cookie、個人情報は含めません。

ETagや更新日時は、機密情報でなくても対象の状態を示す値です。公開の相談文には必要以上に貼らず、サポートが求める場合は安全な窓口で共有してください。

2.前回処理の結果を先に確認する

対象を読み直し、更新日時、本文、状態、外部IDを確認します。作成処理なら同じIDのデータがすでにないか、決済や注文なら外部サービス側の取引結果も見ます。反映済みなら、再送ではなく表示・同期の更新だけで済む場合があります。

画面に412が出たことだけを理由に「失敗」と断定しないでください。要求を処理した後に応答が失われた可能性を確認してから、次の操作を決めます。

3.最新状態を取得して3つの版を比較する

現在サーバーにある版、自分が送ろうとした版、可能なら編集開始時の版を並べます。本文だけでなく、タイトル、公開状態、カテゴリー、カスタムフィールド、更新者、更新日時を確認します。

WordPress公式のリビジョン解説にあるとおり、リビジョンは保存済みの版を比較・復元する助けになります。自動保存も含め、差分を確認する前に古い版や現在版を削除しないでください。

どの層が412を返したか特定する

確認層見るもの判断の手がかり
ブラウザ・編集アプリ条件ヘッダー、保存キュー、キャッシュ古いETagや日時を再利用したか
WordPress本体投稿ロック、リビジョン、更新者、更新日時別編集の痕跡があるか
テーマ・プラグインREST名前空間、独自更新条件、ログどの機能が412を生成したか
外部API外部ドメイン、API版、ETag、リクエストID外部側の現在状態と条件が違うか
CDN・APIゲートウェイ応答ヘッダー、キャッシュ規則、転送設定条件ヘッダーを変更・評価したか

ブラウザのNetwork欄で、412になった要求のURL、HTTPメソッド、Request Headers、Responseを確認します。条件ヘッダーが画面側から送られたのか、プラグイン・外部アプリが付けたのかを分けます。

RFC 9110のIf-Matchは、複数の利用者が並行して同じ対象を更新するときの意図しない上書きを防ぐ用途を説明しています。If-Matchは強い比較を使うため、弱いETagは条件に一致しません。

RFC 9110のIf-Unmodified-Sinceは、ETagがない場合に最終更新日時を条件として使う仕組みです。If-Matchもある場合はIf-Matchが優先されます。

REST応答がHTMLへ変わる、エラー本文を読めない場合は、WordPressのJSONレスポンスエラーを直す手順も併用し、元の412応答を確認します。

送信した検証キーと現在版の状態を精密に照合する立体的な設備

原因別の安全な直し方

1.最新内容を取得し、必要な差分を統合する

現在版を取得し、自分の退避内容と比較します。他者の変更を残したまま、自分の必要な修正だけを適用した新しい内容を作ります。競合箇所を理解できないまま、現在版を全面的に置き換えないでください。

同時編集が続く場合は、担当箇所と保存順を決めます。WordPressの投稿ロックやリビジョンは邪魔な機能として外さず、変更を守る手がかりとして使います。

2.新しく取得したETagを仕様どおりIf-Matchへ使う

APIがIf-Match更新に対応している場合は、最新の取得応答からETagを受け取り、その値を変更せず更新要求へ付けます。取得先と更新先の対象ID、API版、表現形式が同じかも確認します。

ETagの引用符、W/、大文字・小文字を独自に正規化しません。取得した応答にETagがない場合は、推測で生成せず、APIが別の版番号や更新日時を求めていないか確認します。

3.更新日時はサーバーの値とHTTP日付形式を使う

If-Unmodified-Sinceを使う場合は、対象取得時にサーバーが返したLast-Modifiedを基にします。端末の現在時刻、WordPress画面のローカル表示、データベースの別タイムゾーンを混ぜないでください。

日時は秒未満の精度を表現できず、ETagより正確でない場合があります。APIがETagを提供するならIf-Matchを優先し、提供しない場合だけ公式仕様に沿って日時条件を使います。

4.作成条件では既存対象を確認する

If-None-Matchで「まだ存在しないこと」を条件に作成して412になったら、同じID、スラッグ、外部キーの対象を検索します。前回作成済みなら既存対象を使い、本当に別物なら運用ルールに沿う一意値を発行します。

412を避けるため毎回別IDで作成すると、重複データを増やします。削除済み、下書き、ゴミ箱、外部サービス側の記録も確認してください。

5.古いキャッシュと送信キューを安全に作り直す

最新状態を取得しても古い条件が送られる場合は、編集アプリ、Service Worker、連携プラグイン、ジョブキューが保存している版情報を確認します。未処理・処理済みを照合し、古い要求だけを停止します。

キャッシュ削除後は、対象を新しく取得し直してから編集します。古い本文だけを貼り戻して全面上書きせず、現在版との統合内容を使います。

6.API側は条件失敗を具体的に返す

独自REST APIの開発者は、412だけでなく、どの条件が成立しなかったか、最新状態の再取得方法、競合解消の手順を、秘密情報を含めず応答へ示します。リクエストIDで画面とログを対応づけます。

更新APIで条件を必須にするなら、取得応答でETag等を提供し、412と428の使い分け、再取得と再送の例を文書化します。条件を外せば更新できる抜け道を安易に残さないでください。

最新状態から更新した検証キーが一致し安全に処理される設備

やってはいけない対処

  • 編集内容を退避せず画面を再読み込みする
  • If-Match等を削除して強制上書きする
  • 古いETagを何度も同じまま再送する
  • ETagの引用符やW/を手作業で削る
  • 端末の現在時刻をIf-Unmodified-Sinceへ推測で入れる
  • 前回結果を見ず、別IDで作成し直す
  • 投稿ロック、リビジョン、競合検知を無効化する
  • 複数プラグイン、キャッシュ、API設定を同時に変える
  • 本番の決済、注文、通知を連打する

条件付き更新は、古い版による上書きを防ぐ安全機構です。412を消すことだけを目的に条件を外すと、成功表示の裏で他者の変更が失われるおそれがあります。

復旧後の確認チェックリスト

  • 最新状態に必要な変更がすべて統合されている
  • 他者や外部同期の変更が消えていない
  • 新しいETagまたは更新条件で一度だけ成功した
  • 前回処理との重複データがない
  • 投稿、注文、会員、通知の状態が一致する
  • リビジョンと投稿ロックが正常に働く
  • 古い送信キューやオフライン要求が残っていない
  • キャッシュ更新後も古い条件を送らない
  • 条件ヘッダーを外す暫定処理が残っていない
  • 別ユーザー、別タブ、通常操作で再発しない

公開URL自体が412を返し続ける場合は、編集APIだけの問題として放置できません。GoogleのHTTPステータスコード解説では、429を除く4xxを返すURLを検索処理上「内容が存在しない」ものとして扱い、既存URLはインデックスから除かれ得ると説明しています。通常の公開ページとサイトマップ掲載URLが200を返すことも確認します。

自力で直せないときに伝える情報

  • 412が出た日時とタイムゾーン
  • 操作画面、対象URL、RESTルート、HTTPメソッド
  • 投稿・商品・注文等の対象ID
  • If-Match、If-None-Match、If-Unmodified-Sinceの有無
  • 秘密値を伏せた応答コード、メッセージ、リクエストID
  • 取得版と現在版のETag・Last-Modifiedの違い
  • 同時編集、同期、キャッシュ、オフライン利用の有無
  • 直前に更新したWordPress、プラグイン、API版
  • 前回処理の成功有無と、すでに試した対処

相談先は発行元に合わせます。プラグインの独自RESTルートなら開発元、外部ドメインならサービス提供元、CDNやゲートウェイで条件が変わるならその管理者です。認証情報とCookieは共有しないでください。

よくある質問

412と409はどう違いますか?

412はIf-Match等、要求ヘッダーに指定した前提条件が偽になった状態です。409は、要求が対象の現在状態と競合する、より一般的な状態です。実装によって選び方は異なるため、応答本文とAPI仕様を確認します。

キャッシュ削除で直りますか?

古いETagや更新日時をキャッシュが保持している場合は役立ちますが、最新内容との競合はキャッシュ削除だけでは解決しません。編集内容を退避し、現在版を取得して差分を統合してください。

If-Matchを削除してもよいですか?

APIが条件なし更新を明示的に許可し、上書き影響を確認できる場合を除き、削除を回避策にしないでください。If-Matchは更新消失を防ぐためにあります。最新ETagで再送するのが基本です。

WordPressの投稿ロックと同じですか?

同じではありません。投稿ロックはWordPressの同時編集保護、412はHTTP条件付き要求の失敗です。ただし、どちらも古い編集による上書きを防ぐため、調査では更新者、リビジョン、現在版を一緒に確認します。

まとめ

412 Precondition Failedは、要求ヘッダーに指定した前提条件が現在のサーバー状態で成立しないため、処理を適用しなかった状態です。ETag、更新日時、If-None-Match、前回処理の結果を順に確認します。

  • 編集内容を退避し、再送を止める
  • 条件ヘッダーと412の発行元を特定する
  • 前回結果と対象の最新状態を確認する
  • 現在版と送信版の差分を統合する
  • 最新の検証子を仕様どおり使い、一度だけ再送する

412を邪魔なエラーとして回避せず、古い版による上書きを止めた安全機構として扱うことが、内容を失わない復旧につながります。

-速度改善・安全対策