웹을 운영하다 보면 어느 날 갑자기 400 bad request가 쏟아지며 페이지가 열리지 않는 상황을 맞곤 합니다.
이 코드는 서버가 “요청 자체를 이해할 수 없다”고 판단했을 때 돌아오며, MDN 정의와 RFC 9110 기준으로는 잘못된 요청 문법, 프레이밍, 혹은 의심스러운 라우팅이 대표 원인입니다. 아래는 2025년 최신 기준으로 현장에서 바로 쓰는 5단 점검 순서와 서버별 튜닝 포인트를 정리한 가이드입니다.
본문 목차
① 요청 문법·본문 포맷 오류(필수 점검) ② 헤더·쿠키 과다/손상으로 인한 400 bad request ③ URL/쿼리·인코딩·URI 길이 문제 ④ 프록시·CDN·WAF 레이어의 400 ⑤ 본문 크기·전송 문제(업로드·청크) 진단·재현 방법(로그, cURL, 브라우저) 한 눈에 보는 400 진단 표
① 요청 문법·본문 포맷 오류(필수 점검)
400 bad request의 절반은 요청 형식 자체가 어긋난 데서 시작합니다. JSON 본문에 따옴표가 빠졌거나, Content-Type과 실제 페이로드가 불일치하고, Content-Length가 잘못되거나 헤더 구분의 CRLF가 틀어진 케이스가 대표적입니다. 표준 정의는 MDN 400과 RFC 9110 §15.5.1을 확인하세요.
빠른 해결: API 요청을 원문 그대로 재현해 보세요. 브라우저 DevTools에서 “Copy as cURL”로 추출한 뒤 아래처럼 검증합니다.
# JSON 문법·헤더 일치 확인 curl -v https://api.example.com/users \ -H "Content-Type: application/json" \ --data '{"email":"a@example.com","username":"a"}'
② 헤더·쿠키 과다/손상으로 인한 400 bad request
길어진 Cookie, 인증 토큰, 리퍼러 등으로 요청 헤더가 한도를 초과하면 서버가 400을 돌려줄 수 있습니다. 올바른 상태코드는 보통 431 Request Header Fields Too Large이지만, 현실적으로 400으로 응답하는 서버·프록시도 흔합니다. NGINX는 헤더가 내부 버퍼를 넘으면 400으로 실패할 수 있으며(client_header_buffer_size · large_client_header_buffers 참고), IIS/Windows 통합 인증 환경에서도 Kerberos 토큰이 커지면 400이 납니다(MS 문서, IIS 400 트러블슈팅). CDN/프록시 단인 Cloudflare 400 가이드도 참고하세요.
빠른 해결: 사용자 측은 사이트별 쿠키를 먼저 삭제하고(Chrome 쿠키/캐시 삭제), 운영자는 헤더 길이를 줄이거나 서버 한도를 조정합니다.
# (NGINX) 헤더 버퍼 상향: 매우 신중히, 필요한 경로에만 large_client_header_buffers 4 16k; client_header_buffer_size 4k;
# (Apache) httpd.conf 또는 가상호스트 LimitRequestFieldSize 16384
③ URL/쿼리·인코딩·URI 길이 문제
지나치게 긴 쿼리스트링, 적절치 않은 퍼센트 인코딩, 한글·특수문자 처리 오류도 400 bad request로 귀결되기 쉽습니다. 이때는 400 대신 414 URI Too Long이 더 적절하지만, 프록시/게이트웨이에서 400으로 뭉뚱그려 반환되는 경우가 있습니다. GET으로 보내던 대용량 파라미터는 POST 본문으로 옮기고, 서버에선 요청 라인 한도를 확인하세요(Apache LimitRequestLine).
④ 프록시·CDN·WAF 레이어의 400
원본 서버는 정상이어도, Cloudflare·Azure WAF·리버스 프록시에서 필터링·크기 제한·규칙 매칭으로 400이 날 수 있습니다. 예를 들어 Azure WAF는 요청 크기 기본 한도를 넘으면 차단할 수 있고, 프론트 프록시가 내부로 전달하는 과정에서 잘못된 경로나 헤더를 주입해도 400이 발생합니다(참고: IIS 400 가이드, Cloudflare 400).
빠른 해결: 프록시를 잠시 꺼서 원본에 직결해 재현해 보거나, 방화벽 룰·업로드/헤더 크기 정책을 조정해 임계값을 맞춥니다. Kubernetes Ingress-NGINX를 쓴다면 client-header-buffer-size 같은 ConfigMap 옵션을 점검하세요.
⑤ 본문 크기·전송 문제(업로드·청크)
대용량 업로드가 프록시/서버의 한도를 넘으면 원칙적으로 413 Content Too Large가 되어야 하지만, 프론트 레이어가 이를 400으로 바꿔 보내는 환경도 있습니다. 이 경우 NGINX client_max_body_size·Apache LimitRequestBody·IIS maxAllowedContentLength를 정책에 맞춰 조정하세요.
진단·재현 방법(로그, cURL, 브라우저)
첫째, 브라우저 DevTools 네트워크 탭에서 실패 요청을 선택해 요청 헤더·본문을 원형 그대로 확인합니다. 둘째, 서버 접근 로그와 에러 로그에 $request_length·$http_cookie 등 길이를 함께 남기면 과다 헤더/쿠키를 금방 잡아낼 수 있습니다. 셋째, cURL로 간단히 재현해 보세요. cURL/HTTPie 문서: curl.se, HTTPie.
# 헤더 길이/쿠키 분리 전송 테스트 curl -v https://example.com/endpoint \ -H "Cookie: session=..." \ -H "X-Client: test" \ --data '{"ok":true}'
# NGINX 커스텀 로그(길이 관찰) 예시 log_format len '$remote_addr [$time_local] "$request" ' 'len=$request_length cookie="$http_cookie" ' 'ua="$http_user_agent" status=$status'; access_log /var/log/nginx/access_len.log len;
한 눈에 보는 400 진단 표

| 증상 | 가능 원인 | 확인 방법 | 해결(서버별) | 참고 문서 |
|---|---|---|---|---|
| 요청 후 즉시 400 | 문법 오류, Content-Type 불일치, 길이 헤더 불일치 | DevTools “Copy as cURL”로 재현, 서버 에러로그 | 요청 포맷 고정, 파서 에러 메시지 보강 | MDN 400, RFC 9110 |
| 특정 사용자만 400 | 쿠키 과다/손상, 리퍼러 과다 | 쿠키 삭제 후 재시도, 요청 헤더 길이 확인 | 쿠키 전략 단순화, 헤더 한도 조정 | MDN 431, NGINX 버퍼 |
| 긴 URL에서만 400 | URI 길이/인코딩 문제(원래는 414) | GET→POST로 변경, 서버 요청 라인 한도 확인 | Apache LimitRequestLine, 앱에서 페이로드 전송 |
MDN 414 |
| 프록시 켜면만 400 | CDN/WAF 정책, 내부 라우팅·헤더 변조 | 프록시 바이패스 A/B, WAF 로그 | 규칙 화이트리스트, 크기 한도 조정 | Cloudflare 400 |
| 업로드 때 400 | 본문 크기 초과(표준은 413) | 요청/응답 캡처, 프록시/원본 양쪽 확인 | NGINX client_max_body_size · IIS maxAllowedContentLength |
MDN 413 |
빠른 해결 버튼
브라우저·사용자 측 빠른 조치
400 bad request가 특정 사용자에게만 보이면 쿠키/캐시 삭제가 1순위입니다. Chrome 공식 가이드: 쿠키 및 캐시 삭제. 또한 오래된 DNS 캐시가 원인일 수 있으니 Windows라면 ipconfig /flushdns로 초기화하는 방법을 참고하세요(MS 가이드).
운영 환경별 포인트
NGINX는 요청 헤더를 제한된 버퍼에 읽어들이므로 긴 쿠키/리퍼러가 있으면 400이 발생할 수 있습니다(client_header_buffer_size, large_client_header_buffers). Apache는 LimitRequest* 디렉티브로 요청 라인/헤더/본문 한도를 제어합니다. IIS는 인증 토큰·헤더 길이에 민감하여 관련 문서의 워크어라운드를 참고하세요(IIS 400 트러블슈팅).
관련 링크(본문 중 외부 참고처)
MDN – 400 Bad Request · RFC 9110 §15.5.1 · MDN – 431 Request Header Fields Too Large · MDN – 414 URI Too Long · NGINX Core 모듈 · Apache Core 모듈 · Cloudflare 400 · Ingress-NGINX ConfigMap
FAQ — 400 bad request
Q. 400 bad request와 404 not found는 어떻게 다르나요?
400은 “요청 자체가 잘못됨”, 404는 “요청은 이해했으나 리소스를 못 찾음”입니다. 표준 정의는 RFC 9110을 참고하세요.
Q. 쿠키만 지워도 400이 해결되는 이유는?
쿠키가 길어지면 요청 헤더가 서버 한도를 초과해 400/431이 발생할 수 있습니다. 사이트별 쿠키 삭제가 1차 처방입니다(Chrome 가이드).
Q. 긴 URL에서만 400이 보이면?
실제 원인은 414(URI Too Long)에 가깝습니다. GET 파라미터를 POST 본문으로 옮기고 Apache LimitRequestLine 등 한도를 점검하세요(MDN 414).
Q. 업로드 중 400이 날 때는?
원칙은 413이지만, 프록시/게이트웨이가 400으로 치환하기도 합니다. client_max_body_size(NGINX)·LimitRequestBody(Apache)·maxAllowedContentLength(IIS)를 확인하세요(MDN 413).
Q. 같은 요청을 반복하면 언젠가 통과되나요?
요청 자체가 잘못된 경우 재시도해도 계속 400입니다. 우선 요청 문법·헤더·본문을 바로잡아야 합니다(MDN 400)
Q. Ingress-NGINX에서만 400이면?
Ingress의 버퍼/타임아웃 기본값이 원인일 수 있습니다. client-header-buffer-size 등 ConfigMap을 확인하세요(공식 문서)