HTTPQUERY
한국어

406 Not Acceptable

사용법

406 Not Acceptable 오류가 도착하는 경우, 이 응답은 Accept나 Accept-Language 같은 협상 관련 헤더에 의해 유발됩니다. 클라이언트가 이러한 헤더를 하나 이상 포함하면, 서버는 가능한 한 그 요구 사항을 충족시킵니다.

가장 흔한 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을 추가하거나, 어떤 형식이든 받아들이도록 */*를 사용하세요. 브라우저 개발자 도구(네트워크 탭)나 curl -v로 클라이언트가 실제로 보내는 Accept 헤더를 확인하세요.

Accept-Language 제약을 점검하세요. 서버가 지원하지 않는 언어를 요청하면 이 오류가 발생합니다. 언어 목록을 넓히거나 와일드카드(*) 대체 항목을 추가하세요. 브라우저 언어 설정이 이 헤더를 자동으로 제어합니다. 브라우저의 언어 환경설정에서 조정하세요.

지나치게 제한적인 Accept-Encoding이나 Accept-Charset 값을 제거하세요. 인코딩이나 문자 집합 요구가 좁으면 서버의 선택지가 줄어듭니다. gzip, deflate나 UTF-8 같은 일반적인 값을 허용하세요.

응답 본문에서 사용 가능한 대안을 확인하세요. 서버는 406 응답에 지원되는 표현을 나열하는 경우가 많습니다. 하나를 선택해 협상 헤더를 그에 맞게 조정하세요.

서버 측 콘텐츠 협상 설정을 점검하세요. 잘못 설정된 타입 맵이나 서버에 등록되지 않은 MIME 타입이 예상치 못한 406 응답을 유발합니다. Apache에서는 mod_negotiation과 MultiViews가 타입 맵을 제어합니다. AddType 지시문이 필요한 MIME 타입을 등록하는지 확인하세요.

mod_security나 WAF 규칙을 점검하세요. Apache의 mod_security(및 유사한 WAF)는 요청을 가로채며, Accept 헤더가 아니라 요청 내용에 규칙이 발동하면 406을 반환합니다. 서버 오류 로그에서 ModSecurity 항목을 확인하고 규칙 ID(예: [id “941160”])를 기록하세요. WAF 전체를 끄는 대신 해당 규칙만 허용 목록에 넣으세요.

SecRuleRemoveById 941160

이 예외 설정은 가상 호스트 설정이나 .htaccess 파일에 넣으세요.

최소한의 요청으로 테스트하세요. 모든 협상 헤더를 제거하고 curl로 맨 요청을 보내 서버가 기본 표현을 반환하는지 확인하세요. 맨 요청이 성공하면 협상 헤더를 하나씩 다시 추가해 어느 헤더가 거부를 유발하는지 좁혀 가세요.

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