HTTP 408 Request Timeout — 요청 시간 초과·504와의 차이 원인·해결
페이지가 한참 멈춰 있다가 408 Request Timeout이 떴다. 504와 비슷해 보이지만 방향이 정반대다. 408은 "서버가 완전한 요청을 제때 받지 못해 기다리다 끊었다"는 뜻이다. 서버가 응답을 늦게 준 게 아니라, 클라이언트가 요청을 다 보내지 못했거나 너무 느렸을 때 난다. 느린 네트워크로 본문 전송이 늘어졌거나, 연결만 열어 두고 요청을 안 보냈거나, 오래 놀던 연결을 서버가 정리한 경우다. 이 글은 408이 정확히 무엇인지, 504와 어떻게 다른지, 그리고 원인과 해결·예방을 정리한다.

이 글의 구성
🔎 408 Request Timeout의 의미
408은 4xx, 클라이언트 측에 문제가 있다는 묶음이다. 정확히는 "서버가 기다릴 준비가 된 시간 안에 완전한 요청을 받지 못했다"는 뜻이다. 서버는 연결을 받아 두고 요청이 오기를 기다리는데, 정해진 시간이 지나도 요청이 안 오거나 본문이 끝까지 도착하지 않으면 408을 보내고 연결을 닫는다.
핵심은 방향이다. 문제가 "서버의 처리 지연"이 아니라 "요청이 서버에 늦게·불완전하게 도착한 것"이다. 명세상 서버는 408을 보낼 때 Connection: close 헤더로 연결을 끊겠다는 뜻을 함께 알린다. 그래서 408은 한 번 나면 그 연결은 정리되고, 클라이언트는 새 연결로 다시 시도해야 한다.
핵심 — 요청이 늦은 것이지 처리가 늦은 게 아니다
408은 "서버가 일을 오래 한" 504와 정반대다. 클라이언트가 요청을 제때 다 못 보낸 것이다. 그래서 흔히 느린 업로드, 끊긴 네트워크, 오래 놀다가 닫힌 연결에서 난다. 특히 브라우저가 유휴 keep-alive 연결을 재사용하려는 순간 서버가 그 연결을 막 닫았다면, 멱등 요청은 보통 자동으로 새 연결에 다시 시도된다.
⚖️ 504 Gateway Timeout과의 차이
408을 가장 빠르게 이해하는 길은 504와 나란히 두는 것이다. 둘 다 "시간 초과"지만 누가 누구를 기다리다 지쳤는지가 다르다.
| 구분 | 408 Request Timeout | 504 Gateway Timeout |
|---|---|---|
| 분류 | 4xx (클라이언트) | 5xx (서버) |
| 누가 못 기다렸나 | 서버가 클라이언트의 요청을 기다림 | 게이트웨이가 업스트림 서버 응답을 기다림 |
| 느린 쪽 | 클라이언트의 요청 전송 | 뒷단 서버의 응답 처리 |
한 줄로 정리하면, 408은 "네가(클라이언트) 요청을 너무 늦게 보냈다"이고, 504는 "내(게이트웨이) 뒤의 서버가 응답을 너무 늦게 줬다"이다. 방향이 반대라 손볼 곳도 다르다. 408은 네트워크·클라이언트·연결 쪽을, 504는 뒷단 서버·업스트림 처리 쪽을 본다.
🧩 자주 나오는 발생 원인 4가지
원인 1 — 유휴 keep-alive 연결 종료
가장 흔한 "유령" 408이다. 브라우저나 클라이언트가 재사용하려던 연결을 서버가 유휴 시간 초과로 막 닫은 경우다. 멱등 요청이면 대개 새 연결로 자동 재시도돼 사용자는 알아채지 못한다.
원인 2 — 느린 네트워크로 본문 전송 지연
업로드처럼 본문이 큰 요청을 느린 회선으로 보내다 서버의 본문 수신 타임아웃을 넘긴 경우다. 모바일·불안정한 와이파이에서 큰 파일을 올릴 때 자주 만난다.
원인 3 — 연결만 열고 요청을 안 보냄
클라이언트가 TCP 연결만 맺어 두고 요청 라인·헤더를 제때 보내지 않으면, 서버는 헤더 수신 타임아웃에 걸려 408을 돌려준다. 끊긴 스크립트·버그 있는 클라이언트에서 생긴다.
원인 4 — 서버·프록시의 짧은 타임아웃 설정
Nginx의 client_header_timeout·client_body_timeout, 로드밸런서의 idle timeout이 너무 짧으면 정상 요청도 408로 끊긴다. 큰 업로드를 받는 서비스에서 기본값이 빠듯할 때 발생한다.
💻 재현과 동작 확인
408은 연결을 열어 두고 일부러 요청을 늦게 보내면 재현된다. 헤더를 천천히 흘려보내면 서버의 수신 타임아웃에 걸린다.
# 연결만 열고 요청을 천천히 → 서버가 기다리다 408
curl -i --limit-rate 1 -T big.bin https://example.com/upload
# 본문이 너무 느리면 서버가 끊는다
HTTP/1.1 408 Request Timeout
connection: close
서버 쪽 타임아웃 설정을 보면 어디서 끊는지 알 수 있다. Nginx라면 헤더·본문 수신 대기 시간이 핵심이다.
# Nginx — 요청 수신 타임아웃 (기본 60초)
client_header_timeout 60s; # 헤더 수신 대기
client_body_timeout 60s; # 본문 수신 대기
keepalive_timeout 75s; # 유휴 연결 유지 시간
응답에 connection: close가 붙는지, 그리고 408 직후 연결이 끊기는지 보면 서버가 의도적으로 정리한 것임을 확인할 수 있다. 개발자도구 네트워크 탭에서도 Status 408을 볼 수 있다.
🛠 해결 방법과 예방
408은 "요청이 제때 다 도착하게" 만드는 게 핵심이다. 클라이언트·네트워크 쪽과 서버 설정 쪽으로 나눠 본다.
| 입장 | 해결·예방 |
|---|---|
| 사용자 | 네트워크 점검 후 새로고침·재시도, 안정된 회선에서 다시 업로드 |
| 클라이언트 개발 | 멱등 요청 자동 재시도, 큰 업로드는 청크·재개 업로드로 분할 |
| 서버 | 수신 타임아웃(header·body)·keepalive를 트래픽에 맞게 조정 |
| 프록시·LB | idle timeout을 서버와 정합되게 설정, 너무 짧지 않게 |
타임아웃을 무작정 길게 늘리는 건 답이 아니다. 길게 잡으면 느린·악의적 연결이 자원을 오래 붙잡아, 연결 고갈(slowloris 같은 느린 공격)에 취약해진다. 이 위험은 연결마다 워커를 점유하는 Apache·IIS류에서 특히 크고, 이벤트 기반인 Nginx는 상대적으로 내성이 있지만 그래도 수신 타임아웃을 과도하게 늘리면 노출이 커진다. 큰 업로드 때문이라면 타임아웃을 키우기보다 청크 업로드나 스토리지 직접 업로드로 한 요청의 전송 시간을 줄이는 편이 안전하다.
408은 처리가 느린 504와 정반대다. 요청이 늦게 도착한 것이니, 답은 서버 처리가 아니라 네트워크·연결·전송에 있다.
— 누가 누구를 기다렸는지부터
💬 자주 묻는 질문 5가지
Q1408과 504는 뭐가 다른가요?
408은 서버가 클라이언트의 요청을 기다리다 시간 초과한 것(4xx, 클라이언트 측), 504는 게이트웨이가 뒷단 서버의 응답을 기다리다 초과한 것(5xx, 서버 측)입니다. 방향이 반대라, 408은 네트워크·전송을, 504는 뒷단 서버 처리를 봐야 합니다.
Q2가끔 한 번씩 408이 나는데 큰 문제인가요?
간헐적 408은 유휴 keep-alive 연결을 서버가 닫는 순간 재사용하려다 생기는 흔한 현상입니다. 멱등 요청이면 대개 자동 재시도돼 사용자는 모르고 지나갑니다. 빈번하다면 서버 keepalive와 클라이언트 연결 재사용 설정을 맞춰 보세요.
Q3큰 파일 업로드에서 408이 나요.
느린 회선으로 본문을 보내다 서버의 본문 수신 타임아웃을 넘긴 경우입니다. 타임아웃을 키우는 것보다, 청크(분할)·재개 업로드나 스토리지 직접 업로드로 한 요청의 전송 시간을 줄이는 게 안전합니다. 안정된 네트워크에서 재시도도 도움이 됩니다.
Q4서버 타임아웃을 길게 늘리면 되지 않나요?
부분적으로는 맞지만 주의가 필요합니다. 수신 타임아웃을 너무 길게 잡으면 느린 연결이 자원을 오래 점유해, 느린 요청을 악용한 공격(slowloris)에 취약해집니다. 트래픽 특성에 맞게 적정값을 잡고, 대용량은 전송 시간을 줄이는 설계로 푸는 편이 낫습니다.
Q5408을 받으면 그냥 다시 보내도 되나요?
멱등 요청(GET 등)은 안전하게 재시도할 수 있고, 명세도 클라이언트가 반복할 수 있다고 봅니다. 다만 결제 같은 비멱등 요청은 중복 처리 위험이 있어, 멱등키 같은 장치로 보호한 뒤 재시도해야 합니다. 408은 보통 새 연결로 다시 시도하게 됩니다.
📌 결론
408 Request Timeout은 "서버가 완전한 요청을 제때 받지 못해 기다리다 끊었다"는 신호다. 처리가 느린 504와 방향이 정반대로, 요청이 늦게·불완전하게 도착한 것이다. 그래서 손볼 곳은 서버 처리가 아니라 네트워크·연결·전송 쪽이다.
실무 원칙은 다음과 같다.
⏱ 504와 구분한다. 408은 클라이언트 요청이 늦은 것(4xx), 504는 뒷단 서버 응답이 늦은 것(5xx)이다. 방향이 반대다.
🔁 멱등 요청은 재시도한다. 유휴 연결 종료로 인한 간헐적 408은 새 연결 재시도로 대개 해결된다. 비멱등은 멱등키로 보호한다.
🌐 전송을 가볍게 한다. 큰 업로드는 타임아웃을 키우기보다 청크·직접 업로드로 한 요청의 전송 시간을 줄이고, 서버·프록시 타임아웃은 정합되게 맞춘다.
408 트러블슈팅 체크리스트
본 글은 HTTP 408 응답의 일반적 원인과 해결 방법을 정리한 자료다. 서버·타임아웃 설정 변경은 영향 범위를 확인한 뒤 신중히 적용한다.
#HTTP408 #RequestTimeout #408에러 #408과504차이 #요청시간초과 #keepalive #클라이언트타임아웃 #Nginx #clientbodytimeout #업로드타임아웃 #slowloris #청크업로드 #네트워크 #웹개발 #백엔드
'IT' 카테고리의 다른 글
| HTTP 415 Unsupported Media Type — 미디어 타입 미지원 원인·해결 (0) | 2026.06.28 |
|---|---|
| HTTP 410 Gone — 영구 삭제·404와의 차이·SEO 원인·설정 (0) | 2026.06.28 |
| HTTP 409 Conflict — 충돌·동시 수정·중복 원인·해결 (1) | 2026.06.28 |
| HTTP 422 Unprocessable Entity — 검증 실패·400과의 차이 원인·해결 (0) | 2026.06.28 |
| HTTP 413 Payload Too Large — 요청 본문 초과 원인·해결·예방 (0) | 2026.06.28 |
댓글