티스토리 뷰
목차
텅 빈 화면 대신 마주한 406 Not Acceptable 에러, 당황하지 말고 해결해 보세요!
안녕하세요, 여러분! 웹 서핑을 하거나 열심히 개발한 서비스를 테스트하던 중, 갑자기 마주치는 406 Not Acceptable 에러 메시지에 당황했던 경험, 한 번쯤 있으실 겁니다. 마치 외국인에게 한국어로만 열심히 설명했는데, 상대방이 전혀 알아듣지 못하는 답답한 상황과 비슷하다고 할 수 있죠. 이 에러는 서버가 클라이언트(여러분 또는 여러분의 프로그램)가 요청한 형식으로 응답할 수 없을 때 발생합니다.
"대체 이게 무슨 소리야?", "왜 나한테만 이런 일이?" 하며 좌절하셨다면, 이제 걱정 마세요! 오늘 이 시간에는 406 Not Acceptable 에러의 정체부터 주요 원인, 그리고 명쾌한 해결 방법까지 속 시원하게 파헤쳐 드리겠습니다. 이 글을 끝까지 읽으신다면, 더 이상 406 에러 앞에서 작아지지 않을 거예요!
406 Not Acceptable 에러, 너는 누구냐? (개념 알기)
406 Not Acceptable 에러는 HTTP 상태 코드 중 하나입니다. HTTP 상태 코드는 클라이언트가 서버에 요청을 보냈을 때, 그 요청이 성공적으로 처리되었는지, 아니면 어떤 문제가 발생했는지를 알려주는 일종의 약속된 신호입니다. 우리가 흔히 보는 404 Not Found (페이지를 찾을 수 없음) 에러와 비슷한 맥락이죠.
여기서 "Not Acceptable"이라는 말 그대로, 서버가 클라이언트의 요청을 "수용할 수 없다"는 뜻입니다. 좀 더 구체적으로 말하면, 클라이언트는 HTTP 요청 시
Accept
헤더 라는 것을 통해 "나는 이런 형식(미디어 타입, MIME 타입)의 데이터만 받을 수 있어!"라고 서버에 미리 알려줍니다. 예를 들어,
application/json
(JSON 형식),
application/xml
(XML 형식),
text/html
(HTML 형식) 등이 대표적인 미디어 타입입니다.
만약 서버가 클라이언트가
Accept
헤더에 명시한 형식으로 응답 데이터를 생성할 수 없거나, 해당 미디어 타입을 아예 지원하지 않는다면, 서버는 "미안하지만, 네가 원하는 형식으로는 줄 수가 없어"라는 의미로 406 에러를 반환하는 것입니다.
406 에러, 도대체 왜 발생하는 걸까요?
406 에러는 생각보다 다양한 원인으로 발생할 수 있습니다. 마치 감기의 원인이 바이러스, 면역력 저하 등 다양한 것처럼 말이죠. 주요 원인들을 하나씩 살펴보겠습니다.
1. 클라이언트와 서버의 엇갈린 기대:
Accept
헤더 불일치
가장 흔한 원인입니다. 클라이언트가 서버에게 "나는 XML 형식으로 된 데이터만 원해! (
Accept: application/xml
)"라고 요청했는데, 서버는 "미안하지만, 나는 JSON 형식(
application/json
)으로만 줄 수 있어."라고 하는 상황인 거죠. 이런 경우 서버는 406 에러를 보낼 수밖에 없습니다.
- 핵심 : 클라이언트가 요청한
Accept헤더의 미디어 타입과 서버가 제공할 수 있는 응답의 미디어 타입이 맞지 않을 때 발생합니다.
2. 서버 내부의 복잡한 사정: 애플리케이션 로직 및 설정 오류
때로는 서버 측 애플리케이션 자체에 문제가 있거나 설정이 잘못되어 406 에러가 발생하기도 합니다. 특히 웹 애플리케이션 개발 환경에서는 다음과 같은 경우를 의심해 볼 수 있습니다.
자바 Spring Framework 개발자라면 주목하세요!
- DTO(Data Transfer Object)에
Getter메소드가 없을 때 : 서버가 클라이언트에게 데이터를 보내려면, 객체(DTO)에 담긴 정보를 특정 형식(주로 JSON이나 XML)으로 변환하는 직렬화(Serialization) 과정이 필요합니다. 이때 DTO 클래스의 필드 값을 읽어올 수 있는getter메소드가 없다면, Jackson 같은 라이브러리가 "데이터 포장 상자에 손잡이가 없어서 내용물을 꺼낼 수가 없네!"라며 직렬화에 실패하고 406 에러를 유발할 수 있습니다.- 해결책 : DTO 클래스에 Lombok의
@Getter어노테이션을 사용하거나, 각 필드에 대한 publicgetter메소드를 직접 만들어주세요.
- 해결책 : DTO 클래스에 Lombok의
- @Getter @Setter // 필요에 따라 Setter도 추가 public class UserDto { private String username; private String email; // 생성자, 기타 메소드 등 } ```
-
jackson라이브러리가 없거나 설정이 꼬였을 때 :jackson은 자바 객체를 JSON으로, 또는 JSON을 자바 객체로 변환하는 데 핵심적인 역할을 하는 라이브러리입니다. Spring Boot는 기본적으로jackson을 포함하고 있지만, 만약 의존성이 누락되었거나, 다른 라이브러리와 버전 충돌이 있거나, 커스텀 설정에 오류가 있다면 "JSON 번역기가 고장났거나 아예 없어요!" 상태가 되어 406 에러가 발생할 수 있습니다.- 해결책 : 프로젝트의
pom.xml(Maven) 또는build.gradle(Gradle) 파일에jackson-databind와 같은 관련jackson라이브러리 의존성이 올바르게 포함되어 있는지 확인하고, 필요하다면 추가하거나 버전을 조정해야 합니다.
- 해결책 : 프로젝트의
-
HttpMessageConverter설정이 잘못되었을 때 : Spring MVC는HttpMessageConverter를 사용하여 HTTP 요청 본문을 객체로 변환하거나, 객체를 HTTP 응답 본문으로 변환합니다. 클라이언트가Accept헤더를 통해 요청한 미디어 타입을 처리할 수 있는HttpMessageConverter(예: JSON의 경우MappingJackson2HttpMessageConverter, XML의 경우Jaxb2RootElementHttpMessageConverter)가 Spring 설정에 제대로 등록되어 있지 않거나 구성이 잘못되었다면, "데이터 변환 전문가가 부재중입니다!" 상태가 되어 406 에러가 발생합니다.- 해결책 :
WebMvcConfigurer인터페이스를 구현하고configureMessageConverters또는extendMessageConverters메소드를 오버라이드하여 필요한HttpMessageConverter를 명시적으로 등록하고 설정할 수 있습니다. 대부분 Spring Boot가 알아서 잘 해주지만, 특별한 상황에서는 수동 설정이 필요할 수 있습니다.
- 해결책 :
웹 크롤링 시에도 주의하세요!
-
User-Agent헤더가 없거나 부적절할 때 : 많은 웹 서버는 무분별한 봇(bot)의 접근을 막기 위해User-Agent요청 헤더를 확인합니다. 웹 크롤러가User-Agent헤더를 보내지 않거나, 일반적이지 않은 값을 사용하면 서버는 "손님, 누구신지 먼저 밝혀주셔야 합니다!"라며 정상적인 요청이 아니라고 판단하여 406 에러나 다른 오류를 반환할 수 있습니다.- 해결책 : 웹 크롤링 라이브러리(예: Python의
requests)를 사용할 때, 실제 웹 브라우저의User-Agent문자열을headers옵션에 포함시켜 요청하세요.
- 해결책 : 웹 크롤링 라이브러리(예: Python의
- 서버가 요구하는 특정
Accept헤더를 지키지 않았을 때 : 일부 서버는 특정Accept헤더 값을 가진 요청에만 응답하도록 특별히 구성될 수 있습니다. 마치 "저희 식당은 특정 드레스 코드를 갖춘 손님만 받습니다!"와 같은 경우죠. 크롤러가 이러한 요구사항을 만족시키지 못하면 406 에러가 발생할 수 있습니다.
3. 보이지 않는 벽: 서버 환경 및 보안 설정 문제
때로는 서버 자체의 환경 설정이나 보안 시스템이 406 에러의 원인이 되기도 합니다.
- 웹 서버(Nginx, Apache 등) 또는 WAS(Tomcat 등) 설정 : 서버 설정에서 특정 미디어 타입의 응답만 허용하도록 제한되어 있을 수 있습니다.
- 웹 방화벽 (WAF, 예: ModSecurity) : 서버 보안을 위해 설치된 웹 방화벽의 특정 규칙이 클라이언트의 요청을 위협으로 간주하여 차단하고 406 에러를 반환할 수 있습니다. 이는
Accept헤더 내용이나 다른 요청 파라미터와 관련될 수 있으며, 마치 "과도한 경호로 인해 정상적인 손님도 출입을 거부당하는" 상황과 비슷합니다.- 해결책 (서버 관리자) : ModSecurity와 같은 웹 방화벽 로그를 확인하여 차단 원인이 된 규칙을 파악하고, 해당 규칙을 조정하거나 예외 처리해야 합니다. 웹 호스팅 서비스를 이용하는 경우, 호스팅 업체에 문의하여 지원을 받아야 할 수 있습니다.
- SSL/HTTPS 인증서 문제 : 매우 드물지만, SSL 인증서 구성 오류나 HTTP/HTTPS 프로토콜 불일치로 인해 406 에러가 발생하는 경우도 보고됩니다. 예를 들어, HTTPS로만 서비스되는 페이지에 HTTP로 접근하려고 하거나, 그 반대의 경우에 문제가 생길 수 있습니다.
4. 혹시 내 컴퓨터가 문제? 클라이언트 측 설정 점검
놀랍게도, 때로는 문제의 원인이 서버가 아닌 클라이언트 측에 있을 수도 있습니다.
- 브라우저 확장 프로그램 : 일부 브라우저 확장 프로그램이 요청 헤더를 변경하거나 네트워크 요청에 영향을 미쳐 406 에러를 유발할 수 있습니다.
- 프록시 서버 또는 VPN : 프록시 서버나 VPN을 사용하는 경우, 해당 서비스가 요청을 변경하거나 서버와의 통신에 문제를 일으켜 406 에러가 발생할 수 있습니다.
- 잘못된 브라우저 설정 또는 오래된 캐시 : 오래된 캐시 데이터나 잘못된 브라우저 설정이 원인이 될 수도 있습니다.
406 에러, 이제는 안녕! (해결 방법 및 디버깅 절차)
자, 이제 406 에러의 다양한 원인들을 살펴봤으니, 이 답답한 에러로부터 탈출할 방법을 알아볼 차례입니다. 문제 해결의 열쇠는 체계적인 접근과 정확한 진단에 있습니다.
1단계: 요청 헤더 점검 -
Accept
헤더부터 살펴보자!
가장 먼저 클라이언트가 서버로 보내는
Accept
헤더를 확인해야 합니다.
- 브라우저 개발자 도구(F12) 활용 : 웹 브라우저에서 F12 키를 눌러 개발자 도구를 열고, '네트워크(Network)' 탭에서 해당 요청을 선택한 후 '헤더(Headers)' 섹션을 살펴보세요. 여기에 클라이언트가 보낸
Accept헤더 값이 명시되어 있습니다. - 서버 API 문서 확인 : 서버가 어떤 미디어 타입을 지원하는지 API 문서를 통해 확인하거나, 이전에 성공했던 요청의
Accept헤더를 참고하세요. - API 테스트 도구 활용 : Postman, Insomnia, curl과 같은 API 테스트 도구를 사용하여 다양한
Accept헤더 값(예:application/json,application/xml,text/plain, 심지어*/*(모든 미디어 타입 허용))으로 요청을 보내보면서 서버의 반응을 테스트해 볼 수 있습니다.
2단계: 서버 로그 확인 - 단서는 언제나 현장에 있다!
클라이언트 측에서 특별한 문제를 찾지 못했다면, 이제 서버 측 로그를 살펴볼 차례입니다.
- 웹 서버 로그, WAS 로그, 애플리케이션 로그 등을 자세히 확인하여 406 에러 발생 시점의 구체적인 오류 메시지나 스택 트레이스(stack trace)를 찾아보세요. 이는 문제의 근본적인 원인을 파악하는 데 매우 중요한 단서가 됩니다. "어떤 요청을 처리하다가, 어떤 부분에서 문제가 생겼는지"에 대한 정보가 담겨 있을 가능성이 높습니다.
3단계: 서버 코드 및 설정 검토 (애플리케이션 개발자라면 필수!)
서버 측 개발자라면, 애플리케이션 코드와 설정을 꼼꼼히 검토해야 합니다.
- 앞서 언급된 Spring Framework 환경에서의 DTO
Getter부재, Jackson 라이브러리 문제,HttpMessageConverter설정 등을 다시 한번 점검하세요. - 응답을 생성하는 컨트롤러 메소드의 반환 타입과 실제 반환되는 객체가 클라이언트가 요청한
Accept헤더와 호환되는지 확인해야 합니다.
4단계: 웹 크롤러 코드 수정 (크롤러 개발자라면!)
웹 크롤링 중에 406 에러를 만났다면, 크롤러 코드를 수정해야 합니다.
-
User-Agent헤더 를 실제 브라우저의 값으로 설정해 보세요. - 필요하다면, 대상 웹사이트가 요구하는 특정
Accept헤더 값 을 명시적으로 포함시켜 요청을 보내세요.
5단계: 클라이언트 환경 점검 - 내 PC부터 깨끗하게!
의외의 복병일 수 있는 클라이언트 환경도 점검해 보세요.
- 브라우저 캐시와 쿠키를 삭제 해 봅니다.
- 시크릿 모드(Incognito mode) 또는 다른 브라우저 를 사용하여 접속해 보세요. 이를 통해 브라우저 확장 프로그램이나 특정 설정의 영향을 배제할 수 있습니다.
- 설치된 브라우저 확장 프로그램을 일시적으로 모두 비활성화 하고 테스트해 보세요.
- 프록시 서버나 VPN 사용을 잠시 중지 하고 접속해 보세요.
6단계: 서버 환경 및 보안 설정 점검 (서버 관리자라면!)
서버 관리자라면 서버 환경과 보안 설정을 확인해야 합니다.
- 웹 서버(Nginx, Apache 등) 및 WAS(Tomcat 등) 설정 을 검토하여 특정 미디어 타입만 허용하도록 제한되어 있는지 확인합니다.
- 웹 방화벽(WAF) 로그 를 확인하고, 406 에러를 유발하는 규칙이 있다면 해당 규칙을 조정하거나 예외 처리합니다. 잘 모르겠다면 호스팅 업체나 보안 솔루션 업체에 문의하는 것이 좋습니다.
| 문제 유형 | 주요 점검 사항 | 담당자 역할 |
|---|---|---|
Accept
헤더 불일치 |
클라이언트 요청 헤더, 서버 지원 미디어 타입 확인 | 클라이언트/서버 개발자 |
| Spring DTO Getter 부재 | DTO 클래스 내
Getter
메소드 확인 |
서버 개발자 |
| Jackson 라이브러리 문제 | 의존성 확인, 버전 체크, 설정 오류 점검 | 서버 개발자 |
| HttpMessageConverter 설정 | Spring MVC 설정, 컨버터 등록 여부 확인 | 서버 개발자 |
| 웹 크롤링 헤더 문제 |
User-Agent
,
Accept
헤더 설정 점검 |
크롤러 개발자 |
| 웹 방화벽(WAF) 차단 | WAF 로그 확인, 규칙 조정 | 서버 관리자 |
| 클라이언트 환경 문제 | 브라우저 캐시/확장 프로그램, 프록시/VPN 점검 | 사용자/클라이언트 개발자 |
마치며: 406 에러, 이제 두렵지 않아요!
406 Not Acceptable 에러는 처음 마주하면 당황스럽고 막막할 수 있습니다. 하지만 오늘 함께 살펴본 것처럼, 그 원인은 다양하며 체계적으로 접근하면 반드시 해결의 실마리를 찾을 수 있습니다.
가장 중요한 것은 클라이언트가 무엇을 원하는지(
Accept
헤더)와 서버가 무엇을 제공할 수 있는지 를 명확히 파악하는 것입니다. 마치 대화처럼, 서로가 이해할 수 있는 언어와 방식으로 소통해야 하는 것이죠.
이제 여러분은 406 에러의 원인부터 해결 방법까지 든든한 지식을 갖추셨습니다. 다음에 이 에러 메시지를 다시 만나더라도 당황하지 말고, 오늘 배운 내용을 차근차근 적용해 보세요. 분명 시원하게 문제를 해결하고, 텅 빈 화면 대신 원하던 결과를 마주하게 될 것입니다.
혹시 406 에러와 관련하여 더 궁금한 점이나 공유하고 싶은 경험이 있다면 언제든지 댓글로 남겨주세요! 여러분의 성공적인 문제 해결을 항상 응원합니다!