400 Bad Request 오류 원인과 해결 방법

Advertisement
400 Bad Request 오류란?
400 Bad Request는 서버가 요청을 받았지만 요청 자체에 무언가 잘못된 점이 있어 처리하지 않겠다는 뜻의 HTTP 상태 코드입니다. HTTP 표준(RFC 9110, 15.5.1절)은 이를 서버가 "클라이언트 오류로 보이는 무언가 때문에"("due to something that is perceived to be a client error") 요청을 처리할 수 없거나 처리하지 않으려는 상태로 정의합니다. 잘못된 문법, 유효하지 않은 메시지 프레이밍, 기만적인 요청 라우팅 등이 그 예입니다.
서버가 고장 났다는 뜻인 500 오류와 달리, 400은 요청 쪽을 가리킵니다. 브라우저나 앱이 보낸 URL, 헤더, 쿠키, 데이터가 문제라는 것입니다. 웹사이트는 대개 다른 사람들에게는 정상적으로 작동하고 있습니다.
방문자에게는 좋은 소식입니다. 해결 방법이 보통 내 쪽에 있고 1분이면 끝나기 때문입니다. 대부분의 400 오류는 잘못 입력된 링크나 손상된 쿠키 때문에 생깁니다.
400 오류가 표시되는 방식
메시지는 서버 소프트웨어마다 다르며, 덧붙은 문구가 원인을 알려 주는 가장 좋은 단서인 경우가 많습니다:
| 서버 | 페이지에 표시되는 내용 | 흔한 원인 |
|---|---|---|
| nginx | 400 Bad Request: Request Header Or Cookie Too Large | 쿠키나 헤더가 nginx 제한을 초과함 |
| nginx | 400 Bad Request: The plain HTTP request was sent to HTTPS port | HTTPS를 기대하는 포트로 HTTP를 보냄 |
| Apache | Bad Request: Your browser sent a request that this server could not understand. | 잘못된 형식의 요청 또는 너무 큰 헤더 필드 |
| IIS (HTTP.sys) | Bad Request - Invalid URL. HTTP Error 400. The request URL is invalid. | URL에 허용되지 않거나 잘못 인코딩된 문자가 있음 |
| IIS (HTTP.sys) | Bad Request - Request Too Long. The size of the request headers is too long. | 쿠키가 너무 많거나 너무 큼 |
| 400. That's an error. Your client has issued a malformed or illegal request. | 깨진 URL 또는 손상된 쿠키 |
Advertisement
400 Bad Request의 원인
잘못된 형식의 URL. 엉뚱한
%기호, 공백, 인코딩되었어야 할 문자, 또는 중간에 잘리거나 두 번 붙여 넣은 링크.손상되었거나 너무 큰 쿠키. 로그인, A/B 테스트, 분석 등으로 쿠키를 많이 설정하는 사이트는 Cookie 헤더가 서버 제한을 넘을 수 있습니다. 업데이트 도중 손상된 쿠키도 거부될 수 있습니다.
너무 큰 요청 헤더. 쿠키 외에도 긴 인증 토큰이나 확장 프로그램·프록시가 추가한 헤더가 쌓여 커질 수 있습니다.
API로 보낸 잘못된 데이터. 필수 필드 누락, 잘못된 형식의 JSON, 잘못된
Content-Type헤더.HTTPS 포트로 보낸 HTTP. 로드 밸런서와 리버스 프록시 뒤에서 흔히 발생합니다.
너무 큰 파일. 많은 서버가 413 Content Too Large로 응답하지만, 일부 앱과 프레임워크는 대신 400을 반환합니다.
해결 방법 1: URL 확인하기
주소창을 자세히 살펴보세요. 확인할 문제는 다음과 같습니다:
뒤에 16진수 문자 두 개가 오지 않는
%(%20은 정상,%2나%zz는 비정상).공백,
{ },|,\같은 특이한 문자. 특히 이메일, PDF, 메신저에서 복사한 링크에서 자주 보입니다.두 번 붙여 넣은 링크(
https://example.com/https://example.com/...) 또는 중간에 잘린 링크.추적 파라미터가 붙은 아주 긴 URL.
?부터 뒤쪽을 모두 지우고 다시 시도하세요.
다른 사이트의 링크를 타고 왔다면, 대신 해당 사이트의 홈페이지로 가서 그곳에서 페이지를 찾아 들어가세요.
Advertisement
해결 방법 2: 해당 사이트 하나의 쿠키 삭제하기
이전에 이용한 적 있는 사이트에서 뜨는 400 오류는 대부분 이것으로 해결됩니다. 특히 쿠키나 헤더가 "too large"(너무 큼) 또는 "too long"(너무 김)이라는 메시지라면 더욱 그렇습니다. 모든 사이트의 쿠키를 지울 필요는 없고, 해당 사이트만 지우면 됩니다:
Chrome / Edge: 주소창 왼쪽 아이콘 클릭 → 쿠키 및 사이트 데이터(또는 사이트 설정) → 해당 사이트의 데이터를 삭제한 뒤 새로고침하세요.
Firefox: 자물쇠 아이콘 클릭 → 쿠키 및 사이트 데이터 지우기…
Safari (Mac): Safari → 설정 → 개인정보 보호 → 웹 사이트 데이터 관리… → 사이트 검색 → 제거.
iPhone: 설정 → 앱 → Safari → 고급 → 웹 사이트 데이터 → 해당 사이트를 왼쪽으로 쓸어 넘겨 삭제하세요.
해결 방법 3: 시크릿 창에서 열어 본 뒤 캐시 지우기
시크릿/비공개 창에서 페이지를 열어 보세요(Chrome·Edge는 Ctrl + Shift + N, Firefox는 Ctrl + Shift + P, Safari는 Cmd + Shift + N). 비공개 창은 쿠키와 확장 프로그램 없이 시작되므로, 여기서 페이지가 열린다면 해결 방법 2나 해결 방법 4로 완전히 해결됩니다.
시크릿 창에서도 실패한다면 브라우저 캐시를 지우고(Ctrl + Shift + Delete → 캐시된 이미지 및 파일), 마지막 단계로 DNS 캐시를 플러시하세요. DNS가 400의 원인인 경우는 드물지만, 사이트가 서버를 옮긴 뒤에는 오래된 주소 때문에 요청을 거부하는 서버로 연결될 수 있습니다.
Advertisement
해결 방법 4: 확장 프로그램 끄기 및 파일 크기 확인
개인정보 보호 도구, 헤더 편집기, 쿠폰 찾기 도구, 일부 광고 차단기처럼 요청을 수정하는 확장 프로그램은 서버가 거부하는 방식으로 헤더를 추가하거나 바꿀 수 있습니다. 모두 끈 뒤 새로고침하고, 하나씩 다시 켜 가며 범인을 찾으세요.
업로드할 때 오류가 난다면 더 작은 파일로 시도해 보세요. 이미지를 압축하거나 큰 파일을 나누세요. 서버가 413 대신 400으로 보고하더라도, 이렇게 하면 서버가 크기 때문에 거부하는 것인지 알 수 있습니다.
웹사이트 운영자용: 400 오류의 원인 찾기
사용자들이 사이트에서 400 오류를 보고한다면, 그들이 보는 정확한 메시지와 서버 로그부터 확인하세요. nginx와 Apache는 원인을 info 레벨로 기록하므로, 보이지 않는다면 오류 로그 레벨을 잠시 높이세요. 접근 로그에서는 어떤 URL이 400을 반환하는지 알 수 있습니다. DNS Robot의 HTTP 헤더 확인 도구는 상태 코드, 서버 소프트웨어, 페이지가 보내는 모든 Set-Cookie 헤더를 보여 주므로 계속 커지는 쿠키를 찾는 데 도움이 됩니다.
# 400을 받는 요청은? (nginx combined 로그 형식)
sudo awk '$9 == 400 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head
# nginx가 기록한 원인 (error_log ... info; 설정 필요)
sudo grep -i "client sent\|too large\|bad request" /var/log/nginx/error.log | tail -20Advertisement
"Request Header Or Cookie Too Large" 오류
nginx는 large_client_header_buffers로 설정된 버퍼에 요청 헤더를 읽어 들이며, 기본값은 8KB 버퍼 4개입니다. 헤더 한 줄(보통 Cookie 헤더)이 버퍼 하나에 들어가지 않으면 이 400이 발생합니다. Apache에서 이에 해당하는 제한은 LimitRequestFieldSize이며 기본값은 8,190바이트입니다.
올바른 해결책은 덜 보내는 것입니다. 더 이상 필요 없는 쿠키를 제거하고, 세션 쿠키를 작게 유지하고, 쿠키의 범위를 실제로 사용하는 경로와 서브도메인으로 좁히세요. 큰 SSO(싱글 사인온) 토큰처럼 정말 더 큰 헤더가 필요하다면 제한을 늘리세요:
# nginx (http 또는 server 블록)
large_client_header_buffers 4 16k;
# Apache에서 같은 설정 (httpd.conf / vhost)
# LimitRequestFieldSize 16380"The plain HTTP request was sent to HTTPS port" 오류
nginx는 TLS를 기대하는 포트(보통 443)로 일반 HTTP가 들어오면 이 400을 반환합니다. 흔한 원인은 로드 밸런서나 프록시가 http:// 트래픽을 443 포트로 전달하는 경우, http://example.com:443 형태의 링크, 또는 TLS가 필요 없는 포트까지 TLS를 기대하게 만드는 예전 ssl on; 설정입니다.
각 listen 줄이 실제로 들어오는 트래픽과 일치하는지 확인하세요. HTTPS는 listen 443 ssl;, 일반 HTTP는 listen 80;으로 두고 80에서 443으로 리다이렉트하세요. 앞단의 프록시도 443에는 HTTPS로(또는 80에는 HTTP로) 연결하는지 확인하세요.
API에서 발생하는 400 오류
API는 유효성 검사에 실패한 요청에 400을 사용합니다. API를 호출하고 있다면 응답 본문을 읽어 보세요. 대부분의 API가 어느 필드가 잘못되었는지 설명해 줍니다. 그다음 유효한 JSON을 보내는지, 올바른 Content-Type: application/json 헤더를 붙였는지, 필수 파라미터를 모두 넣었는지 확인하세요.
API를 만드는 쪽이라면 문제를 명시하는 본문을 반환하고(예: {"error": "email is required"}), 형식은 올바르지만 의미상 유효하지 않은 요청에는 422 Unprocessable Content를 고려하세요. 400은 아예 파싱할 수 없는 요청에 남겨 두는 것이 좋습니다.
400 vs 401, 403, 404, 413, 429, 431 비교
| 코드 | 이름 | 의미 |
|---|---|---|
| 400 | Bad Request | 요청 형식이 잘못되었거나 유효하지 않음 |
| 401 | Unauthorized | 로그인하거나 유효한 자격 증명을 보내야 함 |
| 403 | Forbidden | 서버가 요청을 이해했지만 접근을 허용하지 않음 |
| 404 | Not Found | 해당 URL에 아무것도 없음 |
| 413 | Content Too Large | 업로드 또는 요청 본문이 너무 큼 |
| 429 | Too Many Requests | 요청 속도 제한에 걸림 |
| 431 | Request Header Fields Too Large | 헤더(보통 쿠키)가 너무 큼(400을 더 구체화한 코드) |
관련 오류 가이드: 403 Forbidden, 401 Unauthorized, 429 Too Many Requests. 실패하는 대신 리다이렉트가 반복된다면 ERR_TOO_MANY_REDIRECTS를 참고하세요. 리다이렉트 확인 도구로 모든 홉을 확인할 수 있습니다.
페이지가 실제로 무엇을 반환하는지 확인하세요
DNS Robot의 HTTP 헤더 확인 도구는 모든 URL의 상태 코드, 서버 소프트웨어, Set-Cookie 헤더를 전부 보여 줍니다. 400 오류를 확인하고 너무 커진 쿠키를 찾아낼 수 있습니다.
사용해보기 HTTP 헤더 확인Advertisement
자주 묻는 질문
서버가 요청을 받았지만 그 안의 무언가가 잘못된 형식이거나 유효하지 않아 보여 처리를 거부했다는 뜻입니다. 깨진 URL, 너무 크거나 손상된 쿠키, 너무 큰 헤더, API로 보낸 잘못된 데이터 등이 원인입니다.