304 Not Modified(変更なし)

HTTP 304 Not Modifiedの意味、3xxコードなのにリダイレクトではない理由、ETagとLast-Modifiedがどう動かすか、そして大規模サイトでランキングに影響せずクロール効率を間接的に助ける理由を解説します。

初回公開:2026年7月3日 · 最終更新:2026年8月22日 · Advanced
言語
このページには証拠シグナルが1件あります

HTTP 304 Not Modifiedは、条件が偽と評価され、本来なら200になっていた条件付きGETまたはHEADリクエストへのレスポンスです。3xxクラスですがリダイレクトではなく、Locationヘッダーもボディもありません。If-None-Match(ETagと照合)またはIf-Modified-Since(Last-Modifiedと照合)を持つGET/HEADが、リクエストを条件付きにします。2回目の訪問は典型例であり、プロトコル上のルールではありません。バリデーターが一致すると、サーバーはボディなしの304を返し、クライアントはキャッシュコピーを再利用します。SEO上、直接的なランキング効果はありません。Googleはすでにコンテンツを持ち、304は変更がないことを確認するだけですが、SearchがURLのシグナルを再計算することはあります。実際の効果はリソース節約です。変更の少ないURLが多い大規模サイトでは、304によりクローラーが変更されていないページの再ダウンロードを省き、帯域幅とサーバー計算資源を節約できます。Googleはクロール効率を間接的に改善する可能性があると述べていますが、クロールバジェットが他のURLへ自動再配分される保証ではありません。Googleは日付形式の落とし穴がないETagを第一のバリデーターとして推奨し、両方の設定も認めています。コンテンツが実際に変わった場合だけキャッシュを無効化し、フッターの著作権年だけでは無効化しません。304を、別URLへ移動させる301/302/307/308や、送るものが本当にないためボディがない204 No Contentと混同しないでください。

TL;DR — 304は、条件が偽と評価され、本来なら200になっていた条件付きGET/HEADへのレスポンスです(RFC 9110 §15.4.5)。3xxクラスですがリダイレクトではありませんLocationも新しいURLもなく、規範上ボディもありません(「it cannot contain content or trailers」 (翻訳)「コンテンツやトレーラーを含めることはできない」)。条件はIf-None-MatchETagと照合)および/またはIf-Modified-SinceLast-Modifiedと照合)で運ばれます。バリデーターがまだ一致すると、サーバーは304を返し、クライアントはキャッシュを再利用します。SEOへの影響は直接的なランキング効果なしです。Googleはすでにコンテンツを持っていますが、SearchがURLのシグナルを再計算することはあります。大規模サイトではリソースを節約でき(Googleはクロール効率を間接的に改善する可能性があると述べています)、クロールバジェットが他のURLへ自動再配分されることまでは約束していません。Googleのクロール基盤は両方のバリデーターに対応し、日付形式の落とし穴がないETagを第一選択として推奨しています。301/302/307/308(URLを移動させる)や204(送るものが本当にないためボディなし)と区別してください。

仕様上の304の意味

RFC 9110(HTTP Semantics)§15.4.5は、304を正確に定義しています。「The 304 (Not Modified) status code indicates that a conditional GET or HEAD request has been received and would have resulted in a 200 (OK) response if it were not for the fact that the condition evaluated to false.」 (翻訳)「304(Not Modified)ステータスコードは、条件付きGETまたはHEADリクエストを受信し、条件が偽と評価されなければ200(OK)レスポンスになっていたことを示す」。これが規範上の実際のトリガーです。条件が偽になり、本来なら200になった条件付きGET/HEADです。平たく言えば、クライアントは「変更された場合だけこのページを返して」と要求し、サーバーは変更されていないと判断したためボディ送信を省略します。「2回目の訪問」はリクエストが条件付きになる日常的な例です(以前のレスポンスから保存したバリデーターをクライアントが添付します)が、教えやすい例であってルールではありません。仕様は前回訪問を要求せず、条件付きリクエストだけを要求します。 Evidence for this claim RFC 9110 defines 304 Not Modified as the response to a conditional GET or HEAD when the selected representation has not changed and says the response cannot contain content. Scope: HTTP semantics for 304 conditional responses. Confidence: high · Verified: IETF: RFC 9110 §15.4.5 — 304 Not Modified

仕様はこの節で「redirecting」という語も使っています。「the server is therefore redirecting the client to make use of that stored representation as if it were the content of a 200 (OK) response」 (翻訳)「したがってサーバーは、保存された表現を200(OK)レスポンスのコンテンツであるかのように利用するよう、クライアントをリダイレクトしている」とあります。しかし注意深く読むと、クライアントを別URLへではなく、自身のキャッシュへ戻しています。Locationヘッダーも新しいアドレスもありません。304が「リダイレクトか」をめぐる混乱の大半はこの一文が原因です。HTTPの意味ではリダイレクトではありません。

規範上、さらに2点が重要です。

  • ボディは絶対にない。 RFC 9110は「A 304 response is terminated by the end of the header section; it cannot contain content or trailers.」 (翻訳)「304レスポンスはヘッダーセクションの終わりで終了し、コンテンツやトレーラーを含めることはできない」としています。ボディを送る304は仕様違反であり、一部のクライアントは誤動作します。これはスタイルの好みではなく、厳格なルールです。
  • 200と同じメタデータを運ぶ。 サーバーは「MUST generate any of the following header fields that would have been sent in a 200 (OK) response to the same request: Content-Location, Date, ETag, and Vary,」 (翻訳)「同じリクエストへの200(OK)レスポンスで送られたはずの次のヘッダーフィールドを生成しなければならない:Content-Location、Date、ETag、Vary」。該当する場合はCache-ControlExpiresも加わります。304はペイロードを除いた200のヘッダーです。
Evidence for this claim A 304 response terminates after the header section and cannot contain content or trailers. Scope: conditional GET and HEAD Confidence: high · Verified: RFC 9110 §15.4.5: 304 Not Modified

304の実際の動作:条件付きリクエスト

サーバーが突然304を送ることはありません。必ず条件付きリクエストへのレスポンスです。これはクライアントが、以前のレスポンスから保存したバリデーターを添付して条件付きにしたリクエストです。バリデーターは2種類あります。

ETagとIf-None-Match

ETag(エンティティタグ)は、サーバーが200レスポンスに付ける不透明なトークンです。URLのその表現そのものに対するバージョン指紋だと考えてください。次にそのURLをリクエストすると、クライアントは保存した値をIf-None-Matchヘッダーで送り返します。サーバーが比較し、現在のETagがまだ一致すれば何も変わっていないため304を返します。一致しなければ、新しいコンテンツと新しいETagを持つ新鮮な200を返します。

Last-ModifiedとIf-Modified-Since

日付を使う代替方法では、サーバーが200に**Last-Modified**タイムスタンプを付けます。次回、クライアントはそれをIf-Modified-Sinceヘッダーで送り返し、サーバーが日付を比較します。そのタイムスタンプ以降にリソースが変更されていなければ、304です。これは単純ですが粗く(タイムスタンプの粒度にしかなりません)、正確なHTTP-date形式に敏感で、バグの一般的な原因です。両方のバリデーターがある場合は、If-None-Match(ETag)がIf-Modified-Sinceより優先されます。

強いETagと弱いETag

ETagには強いものと弱いものがあり、その違いは重要です。MDNの条件付きリクエストの説明によれば、「strong validation consists of guaranteeing that the resource is, byte to byte, identical to the one it is compared to.」 (翻訳)「強い検証とは、リソースが比較対象とバイト単位で同一であることを保証する」です。弱いETagにはW/が付く(例:ETag: W/"abc123")ため、意味上の同等性だけを示します。MDNの例では、「a page that would differ from another only by a different date in its footer, or different advertising, would be considered identical to the other with weak validation.」 (翻訳)「フッターの日付や広告だけが異なるページは、弱い検証では他方と同一とみなされる」。強いETag(接頭辞なし)はバイト単位の一致が必要な範囲リクエストなどで必要です。圧縮、空白、実体のない軽微な差で全再取得を強制したくない場合は弱いETagが有用です。実務上の落とし穴は、コンテンツをgzip/Brotliで再圧縮するたびにETagが変わったり、負荷分散サーバー間で変化したりすると、不要な再クロールを引き起こすことです。強いか弱いかを意図的に選び、本当に変わっていないコンテンツでは値を安定させてください。

完全なハンドシェイクを手順で見る

  1. 最初のリクエスト → サーバーがコンテンツとETagおよび/またはLast-Modifiedを付けた200 OKを返す。
  2. クライアントが保存 → コンテンツとバリデーターを保存する。
  3. 次のリクエスト → クライアントが保存済みの値とともにIf-None-Matchおよび/またはIf-Modified-Sinceを送る。
  4. サーバーが判断: 変更なし → ボディなしの304 Not Modifiedを返し、クライアントはキャッシュを再利用する。変更あり → 新しいボディと新しいバリデーターを持つ200 OKを返す。 Evidence for this claim RFC 9111 defines validation as checking whether a stored response remains current, typically with a conditional request that can receive 304 Not Modified. Scope: HTTP cache validation; it does not create a Search ranking benefit. Confidence: high · Verified: IETF: RFC 9111 §4.3 — Validation

キャッシュとバリデーターをクロール効率の手段として詳しく扱う内容――条件付きリクエスト全体とクロールバジェットとの関係――は別の関連記事に譲ります。この記事はステータスコードに焦点を当てた内容です。

304とSEO:ランキング効果はないが、クロール効率には実効性がある

SEOについての全体像は、ブログの定型文が示すより狭いものです。304に直接的なランキング効果はなく、ステータスコードがクロールとインデックスに与える影響についてGoogle自身の説明も、インデックスへの効果を限定しています。SearchがURLのシグナルを再計算することはありますが、それ以外では304はページのインデックス方法を変えません。Googleは前回クロール時のコンテンツをすでに持っています。304は何も変わっていないことを確認するだけなので、持っているものを使い続けます。304を返してもランキングボーナスはありません。

304が実際にもたらすのは、クロール効率を間接的に改善できるリソース節約です。Googleの2024年12月のSearch Centralブログ記事「HTTP caching」で、Gary Illyesは次のように明確に述べています。「Especially if you have a large site with rarely-changing content under individual URLs, allowing caching locally may help your site be crawled more efficiently. Google’s crawling infrastructure supports heuristic HTTP caching as defined by the HTTP caching standard, specifically through the ETag response- and If-None-Match request header, and the Last-Modified response- and If-Modified-Since request header.」 (翻訳)「個別URLのコンテンツがめったに変わらない大規模サイトでは、ローカルキャッシュを許可するとサイトがより効率的にクロールされる可能性があります。Googleのクロール基盤はHTTPキャッシュ標準で定義されたヒューリスティックなHTTPキャッシュをサポートし、具体的にはETagレスポンス/If-None-Matchリクエストヘッダーと、Last-Modifiedレスポンス/If-Modified-Sinceリクエストヘッダーを通じて行います。」

同じ記事は、304の正確な仕組みについて、空のボディがなぜ要点なのかを明記しています。クローラーが送ったETagが「matches the current value the server generated, your server should return an HTTP 304 (Not modified) status code with no HTTP body,」 (翻訳)「サーバーが生成した現在の値に一致するなら、サーバーはHTTPボディなしのHTTP 304(Not modified)ステータスコードを返すべき」となった場合、「no HTTP body」 (翻訳)「HTTPボディなし」が重要なのは、「your server doesn’t have to spend compute resources on actually generating content」 (翻訳)「サーバーがコンテンツ生成に計算資源を使う必要がなく」、さらに「doesn’t have to transfer the HTTP body」 (翻訳)「HTTPボディを転送する必要もない」からです。両端の計算と帯域幅を節約できます。下流の効果についてGoogle自身の表現は条件付きです。そのリソース節約がクロール効率を間接的に改善する可能性があります。節約した処理が新規または更新URLへ自動的に再配分されるとは約束していないため、妥当ではあるものの保証されない波及効果を持つリソース節約の仕組みとして扱ってください。

大規模サイトで重要になる理由

数百ページ程度なら、これはほぼ理論上の話です。Googleはどちらにせよサイト全体を問題なくクロールできます。規模に応じて効果は大きくなります。数十万、数百万のURLがあり、その多くがめったに変更されないサイトでは、クローラーが変更のないページの再取得を省けるため、実質的な恩恵があります。Googleの記事はこの読者を想定しており、304を小規模サイト向けの施策として誇張しないのが正直な説明です。

ETagかLast-Modifiedか、そして「変更」の意味

GoogleはETagを第一のバリデーターとして推奨しています。「We strongly recommend using ETag because it’s less prone to errors and mistakes (the value is not structured unlike the Last-Modified value).」 (翻訳)「ETagはLast-Modifiedの値と違って構造化されておらず、エラーやミスが起きにくいため、強く推奨します」。両方を設定するのは問題なく、推奨もされています。Last-Modifiedを使う場合、日付は「must be formatted according to the HTTP standard」 (翻訳)「HTTP標準に従ってフォーマットしなければならない」とされます。Googleが推奨する形式は「Weekday, DD Mon YYYY HH:MM:SS Timezone,」 (翻訳)「曜日、DD Mon YYYY HH:MM:SS タイムゾーン」です。例は「Fri, 4 Sep 1998 19:15:56 GMT」 (翻訳)「Fri, 4 Sep 1998 19:15:56 GMT」で、そうしないと黙って無視される可能性があります。Googleは、クローラーが再クロール時期を判断しやすいよう、Cache-Controlmax-ageフィールドを設定することも勧めています。

Evidence for this claim Google's crawler guidance recommends ETag because its opaque value avoids date-formatting errors, while also allowing both ETag and Last-Modified; this is Google-specific operational advice, not a change to HTTP validator semantics. Scope: HTTP cache validation Confidence: high · Verified: Crawling December: HTTP caching

キャッシュを無効にする価値のある変更を何とするかは、あなたが決めます。Googleの助言は実体のある変更に限定することです。「Our recommendation is that you require a cache refresh on significant changes to your content; if you only updated the copyright date at the bottom of your page, that’s probably not significant.」 (翻訳)「コンテンツに重要な変更があった場合にキャッシュ更新を要求することを推奨します。ページ下部の著作権日付だけを更新したなら、おそらく重要ではありません。」

GooglebotとBingbotが実際にどう扱うか

すべてのクローラーリクエストが条件付きになるわけではありません。Googleのクローラー文書によれば、個々のGoogleクローラーやフェッチャーは、提供するプロダクトによってキャッシュ対応が異なります。GooglebotはSearch向けにURLを再クロールするときのキャッシュに対応しますが、他のGoogleフェッチャーは特定の条件でのみ対応する場合があります。そのため、ヘッダーを正しく設定しても、100%のリクエストにIf-None-Match/If-Modified-Sinceが付くとは考えないでください。Bingについても、条件付きリクエストはGoogleだけの機能ではありません。Bingのクローラーは、少なくとも2008年のLive Searchブログ記事以来、条件付きGETIf-Modified-Sinceと、利用できる場合はIf-None-Matchを送信し、コンテンツが変わっていなければ304を受け入れる)に対応しています。ただし、BingはGoogleの2024年記事に相当する最新の説明を公開していません。仕組みは両検索エンジンに適用される一般的なHTTP動作として扱ってください。

304対応を実装する方法

  1. 200でバリデーターを送る。 サーバー、CDN、アプリを設定し、通常の200レスポンスにETag(推奨)および/または正しくフォーマットしたLast-Modifiedヘッダーを付けます。多くのサーバーやフレームワークは静的ファイルのETagを自動で付けますが、動的レスポンスでは通常、明示的な設定が必要です。
  2. 条件付きヘッダーを受信時に尊重する。 リクエストにIf-None-Match/If-Modified-Sinceが付いてきたら、現在のバリデーターと比較し、一致する場合は(ボディなしの)304、一致しなければ新しい200を返します。静的ファイルサーバーはこれを処理することが多い一方、アプリのルートやエッジワーカーでは接続しない限り処理しないことがよくあります。
  3. 「変更」の意味を決める。 本当に変わっていないコンテンツでETagを安定させ、再圧縮やサーバーごとの差で不必要に変えないようにします。
  4. 典型的な設定ミスを監視する:
    • 常に200 — バリデーターを一度も出さないため、条件付きリクエストが発生せず、効率化の恩恵も得られない。
    • 不安定なETag — コンテンツが変わっていないのに値が変わる(ロードバランサー、再圧縮など)ため、常に再取得を強いる。
    • 古い304 — 危険なものです。コンテンツが実際に変わった後もサーバーが304(または変わらないETag)を返し続け、クローラーとキャッシュが更新を取得できない。ログ分析で捕捉すべきバグであり、304固有の欠陥ではありません。

304と他のステータスコードの違い

304と301/302/307/308

それらが実際のリダイレクトです。301/308(恒久的)または302/307(一時的)はLocationヘッダーを持ち、クライアントを別のURLへ移動させます。301/308は正規化シグナルも渡します。304にはLocationがなく、誰も移動せず、ランキングシグナルも渡しません。同じ3xxファミリーでも番号が同じだけで、役割はまったく異なります。コード別リダイレクトの詳しい説明は各記事にあります(301 redirectの記事とリダイレクトサブハブを参照)。

304と204 No Content

どちらもボディなしですが、理由は完全に異なります。204 No Contentは、サーバーに本当に送るものがないため意図的に空のボディを返す2xx成功です。成功したAPIのDELETE/PUTや、アナリティクスビーコンなどが該当します。304もボディを送りませんが、送るものがないからではなく、「you already have it and it’s still valid.」 (翻訳)「すでに持っていて、まだ有効だから」です。混同しないでください。ページURLの204はインデックス可能なコンテンツがないためソフト404のように扱われることがありますが、304はGoogleがすでに持っているコンテンツの有効性を確認するものです。このコードの全体像は204 No Contentの記事で説明しています。

304に関するよくある誤解

  1. 「304 is a redirect.」 (翻訳)「304はリダイレクトだ」。Locationヘッダーはなく、誰も移動しません。クライアントは自分のキャッシュコピーを再利用します。RFC 9110の「保存された表現を利用するようクライアントをredirecting」という表現は、別URLではなくキャッシュを指しています。
  2. 「304 is an error I need to fix.」 (翻訳)「304は修正が必要なエラーだ」。動作する条件付きリクエスト設定が返す、正しく意図された結果です。クロールやDevToolsで304が見えるのは、キャッシュが動作しているサインです。SERPで最も一般的な誤解の1つです。
  3. 「304 helps rankings.」 (翻訳)「304はランキングに役立つ」。直接的なランキング効果はなく、Googleはインデックスへの効果も限定しています。SearchがURLのシグナルを再計算することはありますが、304はそれ以外のインデックス方法を変えません。効果はGoogleが大規模サイトでクロール効率を間接的に改善する可能性があると述べるリソース節約であり、ランキングシグナルでも、節約分が他のURLへ移る保証でもありません。
  4. 「If my server returns 304, Google will use stale content forever.」 (翻訳)「サーバーが304を返すと、Googleは古いコンテンツを永久に使う」。バリデーターが一致している間だけ304が返ります。コンテンツが実際に変わった瞬間、正しく実装されたサーバーは新しいバリデーター付きの新しい200を返します。本当のリスクは、コンテンツ変更後も304を返し続ける設定ミスのサーバーです。304の性質ではなく、バグです。 Evidence for this claim RFC 9111 defines validation as checking whether a stored response remains current, typically with a conditional request that can receive 304 Not Modified. Scope: HTTP cache validation; it does not create a Search ranking benefit. Confidence: high · Verified: IETF: RFC 9111 §4.3 — Validation
  5. 「ETag and Last-Modified are interchangeable.」 (翻訳)「ETagとLast-Modifiedは互換可能だ」。両方ともバリデーターですが、Last-Modifiedは日付形式に敏感でタイムスタンプの粒度までしかなく、ETagは不透明で正確です(不注意な実装ではサーバー間や再圧縮後に扱いにくく変化することがあります)。GoogleはETagを第一選択として推奨し、可能なら両方を使うよう勧めています。

FAQ

HTTP 304はエラーですか? いいえ。キャッシュが動作していることを示す成功シグナルです。クライアントのキャッシュコピーがまだ有効だという意味です。

304 Not Modifiedはリダイレクトですか? いいえ。番号上は3xxクラスですが、Locationヘッダーがなく、クライアントを新しいURLへ移動させません。

304はSEOやランキングに役立ちますか? 直接的なランキング効果はなく、GoogleがURLのシグナルを再計算する可能性を除けば、インデックスへの効果もありません。変更されていないページをクローラーがスキップできるため帯域幅と計算資源を節約し、Googleが言うように大規模サイトのクロール効率を間接的に改善する可能性があります。

ETagとLast-Modifiedの違いは何ですか? ETagIf-None-Matchで照合する不透明なバージョン指紋です。Last-ModifiedIf-Modified-Sinceで照合するタイムスタンプです。Googleはエラーが起こりにくいETagを推奨しています。

弱いETagと強いETagとは何ですか? 強いETagはバイト単位で同一のコンテンツだと示します。W/が接頭辞に付く弱いETagは、圧縮やフッター日付の変更など軽微な差を許容した意味上の同等性を示します。

ログやクロールレポートで304sが見えるのはなぜですか? クライアントが条件付きリクエストを行い、サーバーがコンテンツに変更がないことを正しく確認しているからです。期待される、良い状態です。

サーバーに304を正しく返させるには? 200ETag/Last-Modifiedを送り、次のリクエストのIf-None-Match/If-Modified-Sinceを尊重します。バリデーターが一致したら、ボディなしの304を返します。

304と204の違いは? どちらもボディなしです。204は送るものがないため、304はすでに有効なコピーを持っているためボディがありません。

Googlebotはすべてのリクエストで条件付きヘッダーを送りますか? いいえ。キャッシュ対応はクローラーによって異なるため、ヘッダーを設定していてもすべてのリクエストが条件付きになるわけではありません。

304レスポンスはボディを持てますか? いいえ。RFC 9110によれば「it cannot contain content or trailers.」 (翻訳)「コンテンツやトレーラーを含めることはできません」。ボディ付きの304は仕様違反です。

Evidence for this claim A 304 response terminates after the header section and cannot contain content or trailers. Scope: conditional GET and HEAD Confidence: high · Verified: RFC 9110 §15.4.5: 304 Not Modified

Try it live

This is a real endpoint on this site — not a simulation. Hit it from the button, open it in a new tab, or curl -i it from your terminal, and the server answers with the actual status code this article is about.

Open in new tab ↗

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.