nginx 413 Request Entity Too Large 5분 진단·해결 가이드
장애 대응 중이라면 결론부터: nginx
error.log에client intended to send too large body가 보이면 99%client_max_body_size(기본 1MB) 문제입니다. 업로드를 처리하는location블록에client_max_body_size 50m;를 넣고nginx -t && systemctl reload nginx하면 끝납니다. 아래에서 정확한 위치와 함께 막히는 다른 계층까지 5분 안에 정리합니다.
방금 전까지 되던 업로드가 갑자기 413?
"어제까지 멀쩡하던 이미지 업로드가 오늘 갑자기 안 돼요." 이런 신고가 들어오면 가장 먼저 응답 코드를 보세요. 413은 502/504와 근본적으로 다릅니다.
- 502/504: 업스트림이 죽었거나 응답이 느려서 게이트웨이가 끊은 것 (백엔드 문제)
- 413 Request Entity Too Large: 클라이언트가 보낸 요청 본문이 너무 커서 nginx가 본문을 다 받기도 전에 끊은 것
즉 413은 백엔드가 멀쩡해도 터집니다. "갑자기" 터진 이유는 대개 업로드되는 파일 크기가 어느 순간 한계를 넘었기 때문입니다. 1MB짜리 썸네일은 통과하다가 1.2MB 사진 하나에서 막히는 식이죠.
이 글은 업로드 본문 크기로 인한 413만 다룹니다. 504/502(타임아웃·업스트림 다운)는 별도 가이드(
nginx 502/504 트러블슈팅)를 참고하세요.
413은 왜 터지나: 메커니즘
nginx에는 client_max_body_size라는 지시어가 있고 기본값은 단 1MB입니다. 요청이 들어오면 nginx는 헤더의 Content-Length(또는 멀티파트 바디의 누적 크기)를 보고, 이 한계를 넘는 순간 본문을 끝까지 받지 않고 즉시 413으로 응답을 끊습니다.
요청이 거부되는 지점은 한 곳이 아닙니다. 본문 크기 제한은 여러 계층에 존재합니다.
브라우저 ──> CDN/WAF ──> nginx ──> 리버스 프록시 ──> 업스트림(PHP/앱)
(본문제한) (1MB) (proxy 제한) (post_max_size 등)어느 한 곳이라도 한계가 작으면 거기서 413이 납니다. 그래서 "어디서 막혔는지"를 먼저 특정하는 게 핵심입니다.
5분 진단 루틴
① error.log 한 줄 확인
tail -f /var/log/nginx/error.log | grep "too large body"다음과 같은 줄이 보이면 nginx가 범인입니다.
*123 client intended to send too large body: 3145728 bytes② curl로 재현
curl -v -F "file=@/path/big.jpg" https://example.com/upload-v로 응답을 자세히 봅니다. 핵심은 두 가지입니다.
- 상태 코드:
HTTP/1.1 413 Request Entity Too Large Server헤더:Server: nginx면 nginx,Server: cloudflare면 CDN/WAF, 다른 값이면 업스트림 가능성
③ 어느 계층이 막는지 구분
| 응답 본문 메시지 | Server 헤더 | 막는 주체 | 조치 |
|---|---|---|---|
413 Request Entity Too Large | nginx | nginx | client_max_body_size 상향 |
413 Payload Too Large | 앱/프레임워크 | 업스트림(앱) | post_max_size, 앱 제한 |
413 + cloudflare/WAF | CDN/WAF | 앞단 | CDN 본문 제한 정책 |
현재 적용된 nginx 값은 이렇게 확인합니다.
nginx -T | grep client_max_body_size아무것도 안 나오면 기본값 1MB가 적용 중이라는 뜻입니다.
계층별 해결
nginx: 어느 블록에 둘 것인가
client_max_body_size는 http → server → location 순으로 상속되고, 하위에서 오버라이드됩니다. 가장 안전한 방법은 업로드 엔드포인트 location에만 큰 값을 주는 것입니다.
http {
client_max_body_size 1m; # 전역은 작게 유지
server {
server_name example.com;
client_max_body_size 10m; # 이 서버 기본값
location /upload {
client_max_body_size 50m; # 업로드만 크게 허용
}
}
}위 설정에서 /upload는 50MB까지, 그 외 경로는 10MB, 다른 서버는 1MB가 적용됩니다. 적용은 항상 문법 검사 후 reload 입니다.
nginx -t && systemctl reload nginxkubernetes(nginx-ingress)라면
컨테이너 환경에서 같은 문제가 어노테이션 누락으로 자주 재발합니다. Ingress에 다음을 추가하세요.
metadata:
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "50m"업스트림 동반 조정
nginx만 키워도 업스트림이 막으면 여전히 413이 납니다. 권장 정합은 nginx ≥ post_max_size ≥ upload_max_filesize 입니다.
| 대상 | 설정 항목 | 예시 값 | 비고 |
|---|---|---|---|
| nginx | client_max_body_size | 50m | 가장 바깥, 가장 크게 |
| PHP | post_max_size | 50M | 전체 POST 본문 |
| PHP | upload_max_filesize | 48M | 개별 파일 |
| Apache | LimitRequestBody | 52428800 | 바이트 단위 |
| nginx→FastCGI | fastcgi_buffers 등 | 적정 | 버퍼 부족 시 임시파일 |
nginx만 50m로 키우고 PHP post_max_size를 2M로 두면, nginx는 통과시키지만 PHP가 본문을 비우고 $_FILES가 빈 배열이 되는 함정에 빠집니다.
client_max_body_size 0의 위험
0은 무제한입니다. 절대 전역에 쓰지 마세요. 공격자가 수 GB 본문을 던지면 디스크와 메모리가 고갈되어 서비스가 마비됩니다.
멀티파트·타임아웃이 함께 터질 때
대용량 업로드는 크기 제한과 시간 제한이 동시에 걸리기도 합니다. 본문은 충분히 큰데 회선이 느려 전송이 길어지면 client_body_timeout(기본 60초)에 걸려 408이나 끊김이 발생할 수 있습니다.
location /upload {
client_max_body_size 50m;
client_body_timeout 120s; # 느린 업로드 허용
}413(크기)과 타임아웃(시간)은 다른 지시어이니 함께 점검하세요. 단, 응답이 502/504라면 이 글이 아니라 업스트림 트러블슈팅이 필요합니다.
실무 한마디
여러 현장을 거치며 느낀 건, 413 신고의 80%는 "nginx는 고쳤는데 PHP/프록시를 안 고쳐서" 두 번 장애가 난다는 점입니다. 그리고 CDN을 새로 붙인 직후, 또는 ingress 어노테이션을 깜빡한 배포 직후에 재발합니다. 그래서 저는 413을 고칠 때 "경로(브라우저→CDN→nginx→앱) 위의 모든 본문 제한을 한 줄씩 적어두고 동시에 맞추는" 체크리스트를 항상 씁니다. 한 계층만 보면 반드시 다음 주에 또 만납니다.
재발 방지·보안 체크리스트
-
client_max_body_size 0(무제한) 사용 금지 - 큰 값은 업로드
location에만 한정 적용, 전역은 작게 - nginx ≥
post_max_size≥upload_max_filesize정합 확인 - kubernetes는
proxy-body-size어노테이션 확인 - CDN/WAF 앞단의 별도 본문 제한 점검
- 업로드 엔드포인트에 인증·확장자 검증·바이러스 검사 적용
- 임시 디렉터리 디스크 고갈 모니터링/알람 설정
자주 묻는 질문 (FAQ)
Q. client_max_body_size를 바꿨는데도 계속 413이 나요.
A. 적용 위치를 확인하세요. nginx -T | grep client_max_body_size로 실제 로드된 값을 보고, 업로드 location이 다른 server나 상위 블록을 상속하는지 점검합니다. ingress/CDN 앞단 제한, PHP post_max_size도 함께 의심하세요.
Q. 413과 504는 어떻게 구분하나요?
A. 413은 "본문이 너무 큼"으로 nginx가 즉시 끊는 것이고, 504는 업스트림 응답이 느리거나 죽은 것입니다. 응답 코드와 error.log의 too large body 여부로 구분합니다. 504는 별도 가이드를 참고하세요.
Q. 설정 적용에 nginx 재시작이 꼭 필요한가요?
A. 재시작(restart)은 불필요합니다. nginx -t로 문법을 검증한 뒤 systemctl reload nginx로 무중단 reload 하면 됩니다.
이 글은 AI 에이전트가 1차 초안을 작성한 뒤, 사람 편집자가 사실관계·출처·톤과 맥락을 검토하여 발행했습니다. 오류나 부정확한 내용이 확인되면 24시간 이내에 정정합니다.
댓글
불러오는 중...