HTTPQUERY
日本語

406 Not Acceptable

使い方

406 Not Acceptable エラーが届く場合、このレスポンスは Accept や Accept-Language といったネゴシエーション関連のヘッダーによって引き起こされます。クライアントがこれらのヘッダーを1つ以上含めた場合、サーバーは可能な限りその要件を満たします。

最も一般的な HTTP の Accept 系ヘッダーは次のとおりです。

Accept:優先するコンテンツタイプを指定します。サーバーはプレーンテキストまたは HTML の表現のいずれかを提供します。この例では、クライアントは HTML を優先しつつプレーンテキストも受け入れます。

Accept: text/html, text/plain

Accept-Encoding:クライアントが受け入れるエンコーディングを指定します。この例では、クライアントは gzip 圧縮のサポートを示しています。

Accept-Encoding: gzip

実際には、サーバーが代わりにデフォルトの表現を提供するため、このエラーが使われることはまれです。その根拠は、クライアントは何もないよりは何かを好むという前提にあります。406 Not Acceptable レスポンスが返される場合、メッセージボディにはクライアントが選択できる利用可能な表現の一覧が含まれます。

注意

406 Not Acceptable は、クライアントの Accept 系ヘッダーに合致するレスポンスをサーバーが生成できないことを意味します(出力形式の問題)。415 Unsupported Media Type は、リクエストボディの Content-Type をサーバーが理解できないことを意味します(入力形式の問題)。406 はクライアントが受け取りたいものについて、415 はクライアントが送ったものについての話です。

SEO への影響

Google のような検索エンジンは、406 Not Acceptable ステータスを返す URL をインデックスしません。以前にインデックスされていた URL がこのステータスコードを返すようになると、検索結果から削除されます。

例

クライアントがフランス語でリソースを要求しますが、ドイツ語版と英語版しか利用できないため、サーバーは 406 Not Acceptable で応答します。

リクエスト

GET /news HTTP/1.1
Host: example.com
Accept-Language: fr

レスポンス

HTTP/1.1 406 Not Acceptable
Content-Type: text/html
Content-Length: 242

<html>
  <head>
    <title>French Language Not Available</title>
  </head>
  <body>
    <p>Please choose a supported language:</p>
    <p><a href="/news/news-de.html">German</a></p>
    <p><a href="/news/news-en.html">English</a></p>
  </body>
</html>

対処方法

406 Not Acceptable は、クライアントのコンテントネゴシエーションのヘッダーに合致する表現がサーバーにないことを意味します。

Accept ヘッダーを見直します。受け入れるメディアタイプを広げます。たとえば text/html に加えて application/json を追加するか、どの形式でも受け入れるために / を使います。クライアントが送信している正確な Accept ヘッダーを調べるには、ブラウザの DevTools(Network タブ)または curl -v を使います。

Accept-Language の制約を確認します。サーバーがサポートしていない言語を要求するとこのエラーが発生します。言語の一覧を広げるか、ワイルドカード(*)のフォールバックを追加します。ブラウザの言語設定がこのヘッダーを自動的に制御します。ブラウザの言語設定で調整してください。

過度に制限的な Accept-Encoding や Accept-Charset の値を取り除きます。狭いエンコーディングや文字セットの要求は、サーバーの選択肢を制限します。gzip、deflate、UTF-8 といった一般的な値を許容してください。

レスポンスボディで利用可能な代替案を調べます。サーバーは 406 レスポンスでサポートする表現を列挙していることがよくあります。1つを選び、それに応じてネゴシエーションのヘッダーを調整します。

サーバー側のコンテントネゴシエーション設定を確認します。サーバー上の type map の設定ミスや MIME タイプ登録の欠落が、予期しない 406 レスポンスを引き起こします。Apache では、mod_negotiation と MultiViews が type map を制御します。AddType ディレクティブが必要な MIME タイプを登録していることを検証します。

mod_security や WAF のルールを確認します。Apache の mod_security(および類似の WAF)はリクエストを傍受し、Accept ヘッダーではなくリクエストの内容にルールが反応すると 406 を返します。サーバーのエラーログで ModSecurity のエントリを確認し、ルール ID(例:[id “941160”])を控えます。WAF 全体を無効化するのではなく、その特定のルールを許可リストに入れます。

SecRuleRemoveById 941160

この除外設定は仮想ホストの設定または .htaccess ファイルに置きます。

最小限のリクエストでテストします。すべてのネゴシエーションヘッダーを取り除き、curl で素のリクエストを送って、サーバーがデフォルトの表現を返すかどうかを判断します。素のリクエストが成功する場合は、どのヘッダーが拒否を引き起こしているかを切り分けるため、ネゴシエーションヘッダーを1つずつ戻していきます。

API のバージョンネゴシエーションを検証します。一部の API はバージョン指定に Accept ヘッダーを使います(例:application/vnd.api.v2+json)。サポートされていないバージョン文字列を送ると 406 になります。API ドキュメントと照らしてバージョンの値を確認します。

コードリファレンス

.NET

HttpStatusCode.NotAcceptable

Rust

http::StatusCode::NOT_ACCEPTABLE

Rails

:not_acceptable

Go

http.StatusNotAcceptable

Symfony

Response::HTTP_NOT_ACCEPTABLE

Python3.5+

http.HTTPStatus.NOT_ACCEPTABLE

Java

java.net.HttpURLConnection.HTTP_NOT_ACCEPTABLE

Apache HttpComponents Core

org.apache.hc.core5.http.HttpStatus.SC_NOT_ACCEPTABLE

Angular

@angular/common/http/HttpStatusCode.NotAcceptable