MiServe DevTools

내 스티커

도구를 여기에 고정하세요. 이 브라우저에 저장됩니다.

HTTP 상태 코드 목록

100부터 511까지 HTTP 상태 코드가 개발자에게 무엇을 뜻하는지, 어느 RFC에서 정의하는지 정리했습니다. nginx, Cloudflare 등이 쓰는 비표준 코드도 함께 담았습니다.

상태 코드 78개

1xx 정보

서버가 요청을 받았고 아직 처리하는 중입니다. 최종 응답 전에 보내는 중간 응답입니다.

100 Continue
서버가 요청 헤더를 받았으므로 클라이언트는 본문을 보내도 됩니다. 클라이언트는 큰 파일을 업로드하기 전에 Expect: 100-continue를 보내 이 응답을 요청합니다. RFC 9110
101 Switching Protocols
Upgrade 헤더의 요청대로 서버가 이 연결의 프로토콜을 바꾸는 데 동의합니다. WebSocket 연결이 이렇게 시작됩니다. RFC 9110
102 Processing
서버가 WebDAV 요청을 받아 아직 처리 중이니 클라이언트가 타임아웃하지 말고 기다려야 한다고 알립니다. 현재 WebDAV 명세에서는 빠졌으며 거의 쓰이지 않습니다. RFC 2518
103 Early Hints
최종 응답 전에 Link 헤더와 함께 보냅니다. 서버가 페이지를 준비하는 동안 브라우저가 리소스를 미리 불러오거나 연결을 열어 둘 수 있습니다. RFC 8297

2xx 성공

요청을 받았고, 이해했고, 수락했습니다.

200 OK
요청이 성공했습니다. 본문에는 결과가 담깁니다. GET이면 리소스, POST면 작업의 결과입니다. RFC 9110
201 Created
요청으로 새 리소스가 생성되었습니다. 보통 Location 헤더에 그 URL이 담깁니다. RFC 9110
202 Accepted
요청이 처리를 위해 수락되었지만 처리가 끝나지 않았고, 실패할 수도 있습니다. 큐에 넣은 작업에서 흔히 쓰입니다. RFC 9110
203 Non-Authoritative Information
요청은 성공했지만, 오리진 서버가 보낸 응답을 프록시가 변경했습니다. RFC 9110
204 No Content
요청이 성공했고 보낼 본문이 없습니다. DELETE, 그리고 클라이언트가 이미 새 상태를 알고 있는 PUT이나 PATCH에서 흔히 쓰입니다. RFC 9110
205 Reset Content
요청이 성공했으며 클라이언트는 요청을 보낸 화면을 초기화해야 합니다. 예를 들어 폼을 비웁니다. 본문은 없습니다. RFC 9110
206 Partial Content
본문에는 Range 헤더가 요청한 바이트 범위만 담깁니다. 다운로드를 이어 받거나 동영상에서 원하는 위치로 이동할 때 쓰입니다. RFC 9110
207 Multi-Status
본문은 여러 리소스 각각의 상태를 담은 XML 문서입니다. WebDAV에서 쓰입니다. RFC 4918
208 Already Reported
WebDAV Multi-Status 응답 안에서, 바인딩의 멤버 중 이미 나열된 것을 표시해 중복되지 않게 합니다. RFC 5842
226 IM Used
본문은 현재 리소스에 델타 같은 인스턴스 조작을 하나 이상 적용한 결과입니다. HTTP 델타 인코딩에 속하며, 구현된 곳은 거의 없습니다. RFC 3229

3xx 리다이렉션

요청을 완료하려면 클라이언트가 추가 작업을 해야 합니다. 보통은 다른 URL로 다시 요청하는 것입니다.

300 Multiple Choices
리소스에 여러 표현이 있어 클라이언트가 그중 하나를 고를 수 있습니다. 선택하는 표준 방법이 없어서 거의 쓰이지 않습니다. RFC 9110
301 Moved Permanently
영구 리다이렉트입니다. 리소스의 새 URL은 Location 헤더에 있으며, 검색 엔진은 보통 기존 URL 대신 이 URL을 색인합니다. 클라이언트는 리다이렉트를 따라갈 때 POST를 GET으로 바꿀 수 있으므로, 메서드를 유지하려면 308을 쓰세요. RFC 9110
302 Found
임시 리다이렉트입니다. 지금은 리소스가 Location 헤더에 있는 다른 URL에 있습니다. 클라이언트는 리다이렉트를 따라갈 때 POST를 GET으로 바꿀 수 있으므로, 메서드를 유지하려면 307을 쓰세요. RFC 9110
303 See Other
응답은 다른 URL에 있으며, 클라이언트는 그 URL을 GET으로 가져와야 합니다. 폼을 POST한 뒤 흔히 쓰는 리다이렉트로, 페이지를 새로 고쳐도 폼이 다시 제출되지 않게 합니다. RFC 9110
304 Not Modified
클라이언트 캐시에 있는 사본이 여전히 최신이므로 본문을 보내지 않습니다. If-None-Match나 If-Modified-Since를 사용한 조건부 요청에 대한 응답입니다. RFC 9110
305 Use Proxy
Location 헤더에 지정된 프록시를 거쳐야 리소스에 접근할 수 있습니다. 보안상의 이유로 지원이 중단되었으며, 클라이언트는 이 코드에 의존하지 않아야 합니다. RFC 9110
306 (Unused)
명세의 이전 버전에서 쓰던 코드입니다. 지금은 쓰이지 않으며, 번호는 예약되어 있습니다. RFC 9110
307 Temporary Redirect
리소스가 일시적으로 다른 URL에 있으며, 클라이언트는 같은 메서드와 본문으로 그 URL에 요청을 다시 보내야 합니다. RFC 9110
308 Permanent Redirect
리소스에 영구적인 새 URL이 생겼으며, 클라이언트는 같은 메서드와 본문으로 그 URL에 요청을 다시 보내야 합니다. RFC 9110

4xx 클라이언트 오류

요청에 클라이언트 측 문제가 있습니다. 형식이 잘못되었거나, 권한이 없거나, 제공할 수 없는 것을 요청한 경우입니다.

400 Bad Request
요청 형식이 잘못되어 서버가 처리할 수 없습니다. 구문이 틀렸거나, 메시지 프레이밍이 올바르지 않거나, 본문을 파싱할 수 없는 경우입니다. RFC 9110
401 Unauthorized
요청에 유효한 자격 증명이 없습니다. 응답의 WWW-Authenticate 헤더가 인증 방법을 알려 줍니다. 이름과 달리 이 코드는 권한이 아니라 인증에 관한 것입니다. RFC 9110
402 Payment Required
향후 사용을 위해 예약된 코드입니다. 일부 API는 구독이 끝났거나 유료 할당량을 다 썼을 때 이 코드를 보냅니다. RFC 9110
403 Forbidden
서버가 요청을 이해했지만 거부합니다. 요청에 자격 증명이 있었다면 그것으로는 이 리소스에 접근할 수 없으며, 다시 보내도 소용없습니다. RFC 9110
404 Not Found
서버의 이 URL에 아무것도 없거나, 서버가 있다는 사실을 밝히고 싶지 않은 경우입니다. 없는 상태가 영구적인지는 알려 주지 않습니다. RFC 9110
405 Method Not Allowed
리소스는 있지만 이 메서드를 지원하지 않습니다. Allow 헤더에 지원하는 메서드가 나열됩니다. RFC 9110
406 Not Acceptable
요청의 Accept, Accept-Language, Accept-Encoding 헤더를 만족하는 응답을 서버가 만들 수 없습니다. RFC 9110
407 Proxy Authentication Required
401과 비슷하지만, 클라이언트가 Proxy-Authenticate 헤더에 설명된 대로 프록시에 인증해야 합니다. RFC 9110
408 Request Timeout
서버가 기다릴 수 있는 시간 안에 요청 전체를 받지 못해 연결을 닫습니다. RFC 9110
409 Conflict
요청이 리소스의 현재 상태와 충돌합니다. 예를 들어 오래된 버전을 기준으로 한 수정이나, 고유해야 하는 값의 중복이 있습니다. RFC 9110
410 Gone
리소스가 이곳에 있었지만 영구적으로 삭제되었습니다. 404와 달리 클라이언트와 검색 엔진에 이 URL을 지워도 된다고 알려 줍니다. RFC 9110
411 Length Required
Content-Length 헤더가 없어서 서버가 요청을 거부합니다. RFC 9110
412 Precondition Failed
If-Match, If-Unmodified-Since 같은 헤더의 조건이 거짓이어서 요청이 적용되지 않았습니다. 다른 사람이 변경한 내용을 덮어쓰지 않도록 막아 줍니다. RFC 9110
413 Content Too Large
요청 본문이 서버가 허용하는 크기보다 큽니다. 보통 서버나 그 앞의 프록시에 설정된 업로드 제한 때문입니다. 이전 이름은 Payload Too Large였습니다. RFC 9110
414 URI Too Long
URL이 서버가 허용하는 길이보다 깁니다. POST 본문에 넣어야 할 데이터를 쿼리 문자열에 넣은 경우가 많습니다. RFC 9110
415 Unsupported Media Type
Content-Type이나 Content-Encoding 헤더에 선언된 요청 본문의 형식을 서버가 받아들이지 않습니다. RFC 9110
416 Range Not Satisfiable
Range 헤더가 리소스 범위를 벗어난 바이트를 요청합니다. RFC 9110
417 Expectation Failed
요청의 Expect 헤더에 지정된 요구 사항을 서버가 충족할 수 없습니다. RFC 9110
418 I'm a teapot
Hyper Text Coffee Pot Control Protocol에서 나온 만우절 농담으로, 찻주전자가 커피 끓이기를 거부한다는 내용입니다. RFC 9110은 이 번호를 사용하지 않는 것으로 두고 예약해 두었습니다. 농담으로 너무 많이 배포되어 다른 의미를 부여할 수 없기 때문입니다. RFC 2324, RFC 9110
421 Misdirected Request
이 호스트 이름에 응답하도록 설정되지 않은 서버에 요청이 도달했습니다. 브라우저가 HTTP/2 연결을 다른 호스트에 재사용할 때 발생할 수 있으며, 클라이언트는 새 연결로 다시 시도할 수 있습니다. RFC 9110
422 Unprocessable Content
요청의 구문은 올바르지만 내용이 유효하지 않습니다. 예를 들어 JSON 본문이 유효성 검사를 통과하지 못한 경우입니다. WebDAV에서 나온 코드로, 그곳에서의 이름은 Unprocessable Entity였습니다. RFC 9110, RFC 4918
423 Locked
WebDAV 리소스가 잠겨 있어 메서드를 적용할 수 없습니다. RFC 4918
424 Failed Dependency
이 WebDAV 리소스가 의존하는 다른 작업이 실패해서 메서드가 실행되지 않았습니다. RFC 4918
425 Too Early
TLS early data로 도착한 요청은 재전송 공격일 수 있으므로 서버가 처리하지 않습니다. 클라이언트는 핸드셰이크가 끝난 뒤 다시 보내야 합니다. RFC 8470
426 Upgrade Required
서버가 이 프로토콜로 온 요청을 거부하고, 클라이언트가 전환해야 할 프로토콜을 Upgrade 헤더에 지정합니다. RFC 9110
428 Precondition Required
서버는 If-Match 등을 사용한 조건부 요청을 요구합니다. 업데이트가 더 새로운 버전을 모르게 덮어쓰는 일을 막기 위해서입니다. RFC 6585
429 Too Many Requests
클라이언트가 일정 시간 동안 너무 많은 요청을 보내 속도 제한(rate limiting)에 걸렸습니다. Retry-After 헤더로 얼마나 기다려야 하는지 알려 줄 수 있습니다. RFC 6585
431 Request Header Fields Too Large
헤더 전체 또는 그중 하나가 서버가 허용하는 크기보다 큽니다. 너무 큰 쿠키가 흔한 원인입니다. RFC 6585
451 Unavailable For Legal Reasons
법원 명령 같은 법적 요구 때문에 서버가 접근을 거부합니다. 번호는 소설 《화씨 451》에서 따왔습니다. RFC 7725

5xx 서버 오류

요청은 올바를 수 있지만, 서버나 그 앞단의 게이트웨이가 요청을 처리하지 못했습니다.

500 Internal Server Error
서버가 예상하지 못한 상황을 만났습니다. 처리되지 않은 예외인 경우가 많습니다. 원인은 서버 로그에서 확인해야 합니다. RFC 9110
501 Not Implemented
요청에 필요한 기능을 서버가 지원하지 않습니다. 예를 들어 서버가 알지 못하는 메서드입니다. RFC 9110
502 Bad Gateway
게이트웨이나 프록시가 뒤에 있는 서버로부터 잘못된 응답을 받았습니다. 프록시 뒤의 애플리케이션이 다운되었거나 수신 대기하지 않는 경우가 많습니다. RFC 9110
503 Service Unavailable
과부하나 점검 때문에 서버가 지금은 요청을 처리할 수 없습니다. Retry-After 헤더로 언제 다시 시도할지 알려 줄 수 있습니다. RFC 9110
504 Gateway Timeout
게이트웨이나 프록시가 뒤에 있는 서버로부터 제시간에 응답을 받지 못했습니다. 애플리케이션이 너무 느리거나 연결할 수 없는 경우가 많습니다. RFC 9110
505 HTTP Version Not Supported
요청에 사용된 HTTP 메이저 버전을 서버가 지원하지 않습니다. RFC 9110
506 Variant Also Negotiates
서버 설정 오류입니다. 투명 콘텐츠 협상으로 선택된 변형 자체가 다시 협상하도록 설정되어 있어 루프가 생깁니다. RFC 2295
507 Insufficient Storage
요청을 완료하는 데 필요한 내용을 서버가 저장할 수 없습니다. WebDAV용으로 정의된 코드입니다. RFC 4918
508 Loop Detected
바인딩을 따라가다 무한 루프를 발견해서 서버가 WebDAV 작업을 중단했습니다. RFC 5842
510 Not Extended
서버가 요구하는 확장이 요청에 없습니다. 이 코드를 정의한 명세는 이제 Historic 상태이며, IANA 레지스트리는 이 코드를 폐기된 것으로 표시합니다. RFC 2774
511 Network Authentication Required
네트워크에 접속하려면 클라이언트가 인증해야 합니다. 요청한 사이트가 아니라 호텔 Wi-Fi 로그인 페이지 같은 캡티브 포털(captive portal)이 보냅니다. RFC 6585

비표준 코드

이 코드들은 IANA 레지스트리에 없습니다. 각각 특정 서버나 서비스에서만 쓰이며, 그 의미도 해당 제품 안에서만 통합니다.

419 Page Expired 비표준
폼의 CSRF 토큰이 없거나 만료되었을 때 Laravel이 보냅니다. Laravel
444 No Response 비표준
nginx 설정에서 444를 반환하면 응답을 보내지 않고 연결을 닫습니다. nginx 로그에는 기록되지만 클라이언트는 아무것도 받지 않습니다. nginx
494 Request Header Too Large 비표준
요청 헤더가 버퍼에 들어가지 않을 때 nginx가 내부적으로 사용합니다. 클라이언트에는 400 응답이 전송됩니다. nginx
495 SSL Certificate Error 비표준
클라이언트 인증서 검증에 실패했을 때 nginx가 내부적으로 사용합니다. 설정에서 따로 처리하지 않으면 클라이언트에는 400 응답이 전송됩니다. nginx
496 SSL Certificate Required 비표준
서버가 요구하는 인증서를 클라이언트가 제시하지 않았을 때 nginx가 내부적으로 사용합니다. nginx
497 HTTP Request Sent to HTTPS Port 비표준
HTTPS를 기대하는 포트에 일반 HTTP 요청이 도착했을 때 nginx가 내부적으로 사용합니다. nginx
499 Client Closed Request 비표준
서버가 응답하기 전에 클라이언트가 연결을 닫았을 때 nginx가 로그에 기록합니다. 클라이언트의 타임아웃이 애플리케이션의 처리 시간보다 짧다는 뜻인 경우가 많습니다. nginx
509 Bandwidth Limit Exceeded 비표준
사이트가 할당된 대역폭을 다 썼을 때 cPanel 같은 호스팅 제어판이 보냅니다. cPanel
520 Web Server Returned an Unknown Error 비표준
오리진 서버가 비어 있거나, 알 수 없거나, 예상하지 못한 응답을 반환했을 때 Cloudflare가 보냅니다. Cloudflare
521 Web Server Is Down 비표준
오리진 서버가 Cloudflare의 연결을 거부했을 때 Cloudflare가 보냅니다. Cloudflare
522 Connection Timed Out 비표준
Cloudflare가 제시간에 오리진 서버와 TCP 연결을 완료하지 못했을 때 보냅니다. Cloudflare
523 Origin Is Unreachable 비표준
잘못된 DNS 레코드나 라우팅 문제 등으로 Cloudflare가 오리진 서버에 도달하지 못했을 때 보냅니다. Cloudflare
524 A Timeout Occurred 비표준
Cloudflare가 오리진 서버에 연결했지만, 오리진이 제시간에 HTTP 응답을 보내지 않았습니다. Cloudflare
525 SSL Handshake Failed 비표준
Cloudflare와 오리진 서버 사이의 TLS 핸드셰이크가 실패했을 때 Cloudflare가 보냅니다. Cloudflare
526 Invalid SSL Certificate 비표준
오리진 서버의 TLS 인증서를 검증하지 못했을 때 Cloudflare가 보냅니다. Cloudflare

브라우저에서 실행됩니다. 붙여 넣은 내용은 업로드되지 않습니다.

이 도구에 대하여

상태 코드의 구성

모든 HTTP 응답은 세 자리 상태 코드로 시작합니다. 첫 자리는 클래스를 나타냅니다. 1xx는 중간 응답, 2xx는 성공, 3xx는 클라이언트에게 다른 곳으로 가라는 뜻이고, 4xx는 요청에, 5xx는 서버에 문제가 있다는 뜻입니다. 클라이언트는 모르는 코드를 받으면 해당 클래스의 첫 번째 코드처럼 처리해야 합니다. 따라서 알 수 없는 4xx는 400으로 처리됩니다.

Not Found처럼 번호 뒤에 오는 텍스트는 사유 구문(reason phrase)입니다. 사람을 위한 설명일 뿐이어서 클라이언트는 이를 무시해야 하며, HTTP/2와 HTTP/3에서는 아예 보내지 않습니다. 이 목록에 있는 표준 코드의 이름은 IANA 레지스트리의 이름을 따릅니다. 단, 418은 레지스트리에 (Unused)로 올라 있습니다.

자주 헷갈리는 코드

401과 403. 401은 서버가 사용자가 누구인지 모른다는 뜻이며, 인증하면 해결될 수 있습니다. 403은 서버가 요청을 거부한다는 뜻이며, 다시 인증해도 결과는 바뀌지 않습니다.

301, 302, 307, 308. 301과 308은 영구, 302와 307은 임시 리다이렉트입니다. 301과 302에서는 클라이언트가 리다이렉트를 따라갈 때 POST를 GET으로 바꿀 수 있지만, 307과 308은 같은 메서드와 본문을 유지해야 합니다.

502와 504. 둘 다 애플리케이션 앞에 있는 프록시나 로드 밸런서가 보냅니다. 502는 프록시가 잘못된 응답을 받았거나 연결에 실패한 경우이고, 504는 기다렸지만 제시간에 아무 응답도 받지 못한 경우입니다.

404와 410. 404는 여기에 아무것도 없다는 뜻이며, 일시적일 수도 있습니다. 410은 리소스가 영구적으로 삭제되었다는 뜻입니다.

이 목록의 출처

표준 코드는 IANA HTTP Status Code Registry에서 가져왔습니다. 대부분은 2022년에 RFC 7231을 대체한 RFC 9110(HTTP Semantics)에 정의되어 있습니다. 나머지는 WebDAV와 그 밖의 작은 확장에서 나왔으며, 항목마다 해당 RFC를 표시했습니다. 아직 Internet-Draft 단계인 임시 등록 코드는 제외했습니다. 마지막 그룹에는 등록되지 않았지만 nginx, Cloudflare 등의 로그와 오류 페이지에 나타나는 코드를 모았습니다.

전체 목록이 페이지에 포함되어 있어 JavaScript 없이도 읽을 수 있습니다. 검색창은 브라우저 안에서 목록을 필터링합니다.

자주 묻는 질문

401과 403의 차이는 무엇인가요?

401 Unauthorized는 요청에 유효한 자격 증명이 없다는 뜻이며, 클라이언트는 인증한 뒤 다시 시도할 수 있습니다. 403 Forbidden은 서버가 요청을 이해했지만 거부한다는 뜻입니다. 보낸 자격 증명으로는 접근할 수 없으므로 다시 보내도 소용없습니다.

영구 리다이렉트에는 301과 308 중 무엇을 써야 하나요?

둘 다 클라이언트와 검색 엔진에 URL이 영구적으로 옮겨졌다고 알립니다. 301에서는 클라이언트가 리다이렉트를 따라갈 때 POST를 GET으로 바꿀 수 있지만, 308은 같은 메서드와 본문을 유지해야 합니다. GET으로 요청하는 일반적인 페이지 URL에서는 두 코드가 똑같이 동작합니다.

502와 504의 차이는 무엇인가요?

둘 다 애플리케이션이 아니라 프록시, 게이트웨이, 로드 밸런서가 보냅니다. 502 Bad Gateway는 뒤에 있는 서버가 잘못된 응답을 보냈거나 연결을 거부했다는 뜻입니다. 504 Gateway Timeout은 그 서버가 프록시의 제한 시간 안에 응답하지 않았다는 뜻입니다.

499는 실제 HTTP 상태 코드인가요?

IANA에 등록된 코드는 아닙니다. 응답을 보내기 전에 클라이언트가 연결을 닫으면 nginx가 액세스 로그에 499를 기록하므로, 이 코드를 실제로 받는 클라이언트는 없습니다. Cloudflare의 520~526처럼 다른 제품들도 레지스트리에 없는 번호를 비슷한 방식으로 사용합니다.

네트워크의 다른 도구