URL 모니터링 알림에 404가 찍혔습니다. 다른 날은 500이 찍힙니다. 그런데 둘 사이에 302와 307은 뭐가 다른지, 401과 403은 왜 나뉘어 있는지 물으면 선뜻 답하기 어려운 경우가 많습니다. HTTP 상태 코드는 서버가 클라이언트의 요청을 처리한 결과를 세 자리 숫자로 알려주는 신호 체계입니다. 첫 자리 숫자가 1부터 5까지 다섯 그룹으로 나뉘고, 그룹마다 의미가 다릅니다.
| 첫 번째 숫자 |
그룹 |
의미 |
| 1xx |
정보성 응답 |
요청을 받았고 처리를 계속 진행합니다 |
| 2xx |
성공 |
요청을 성공적으로 받아 처리했습니다 |
| 3xx |
리다이렉션 |
요청을 완료하려면 추가 조치가 필요합니다 |
| 4xx |
클라이언트 오류 |
요청 문법이 잘못됐거나 처리할 수 없습니다 |
| 5xx |
서버 오류 |
서버가 정상적인 요청을 처리하는 데 실패했습니다 |
URL 모니터링은 이 신호 중 4xx와 5xx를 감지해 알림을 보내는 방식으로 동작합니다. 첫 자리가 4나 5인 경우는 정상적인 상황이 아니라서, 사이트 운영자가 곧바로 알아야 하는 정보이기도 합니다. 다만 알림에 찍힌 코드 하나만 보고는 그게 요청 쪽 문제인지 서버 쪽 문제인지, 잠깐 지나가는 문제인지 바로 조치해야 할 문제인지 구분하기 어려울 때가 많습니다. 전체 코드를 한 번 정리해 두면 알림이 올 때마다 코드 하나로 상황을 가늠하는 시간이 줄어듭니다. 이번 정리는 IETF의 RFC 2616(HTTP/1.1 표준 사양)과 이를 계승한 후속 RFC, 모질라 재단(MDN)의 상태 코드 문서를 기준으로 했습니다.
1xx, 요청을 받았다는 신호
HTTP/1.0에서 지원되지 않고, 브라우저 화면에 직접 나타나는 경우도 거의 없습니다.
| 코드 |
이름 |
의미 |
| 100 |
Continue |
지금까지 요청에 문제가 없으니 계속 보내거나, 이미 요청을 끝냈다면 이 응답은 무시해도 됩니다 |
| 101 |
Switching Protocols |
클라이언트가 보낸 Upgrade 요청 헤더에 응답해, 서버가 프로토콜을 전환하겠다고 알립니다. 웹소켓 연결을 맺을 때 주로 나타납니다 |
| 102 |
Processing (WebDAV) |
서버가 요청을 받아 처리 중이지만 아직 완료된 응답을 줄 수 없습니다. WebDAV(웹 문서를 원격에서 편집·관리하는 확장 프로토콜)에서 사용합니다 |
2xx, 요청이 정상 처리됐다는 신호
| 코드 |
이름 |
의미 |
| 200 |
OK |
요청이 성공했고 결과가 응답에 담겨 있습니다. URL 모니터링에서 자주 보이는 코드입니다 |
| 201 |
Created |
요청이 성공했고 그 결과로 새 리소스가 생성됐습니다. 주로 POST나 일부 PUT 요청 뒤에 따라옵니다 |
| 202 |
Accepted |
요청은 받았지만 아직 처리 결과를 알려줄 수 없습니다. 비동기 처리나 배치 작업으로 넘어가는 경우에 쓰입니다 |
| 203 |
Non-Authoritative Information |
응답에 담긴 메타 정보가 원본 서버의 것과 정확히 일치하지 않고, 로컬이나 제3자 사본에서 가져온 것입니다. 이런 상황이 아니면 200이 우선됩니다 |
| 204 |
No Content |
요청은 처리했지만 돌려줄 본문이 없습니다. 다만 헤더는 의미가 있을 수 있어 캐시를 최신 상태로 갱신하는 데 쓰이기도 합니다 |
| 205 |
Reset Content |
요청을 마친 뒤, 요청을 보낸 문서 화면을 초기 상태로 되돌리라고 알려줍니다 |
| 206 |
Partial Content |
클라이언트가 Range 헤더로 파일을 나눠 받으려 할 때 사용됩니다. 이어받기를 시도하면 서버가 지정한 구간부터 데이터를 보내며 이 코드로 응답합니다 |
| 207 |
Multi-Status (WebDAV) |
여러 리소스마다 서로 다른 상태 코드가 섞여 있을 때, 그 결과를 한 번에 전달합니다. WebDAV에서 사용합니다 |
| 208 |
Already Reported (WebDAV) |
같은 컬렉션에 여러 번 바인딩된 멤버를 반복해서 나열하지 않으려고 쓰는 코드입니다. 역시 WebDAV 전용입니다 |
| 226 |
IM Used |
서버가 GET 요청을 처리했고, 응답에 하나 이상의 인스턴스 조작(IM, Instance Manipulation)이 적용됐다는 뜻입니다 |
3xx, 다른 곳으로 가야 한다는 신호
| 코드 |
이름 |
의미 |
| 300 |
Multiple Choices |
요청에 응답할 후보가 여러 개 있어, 그중 하나를 사용자나 사용자 에이전트가 선택해야 합니다. 선택 방법은 표준화돼 있지 않습니다 |
| 301 |
Moved Permanently |
요청한 리소스의 주소가 영구히 바뀌었습니다. 새 주소가 응답에 함께 담길 수 있습니다 |
| 302 |
Found |
주소가 일시적으로 바뀌었습니다. 나중에 다시 바뀔 수 있어 클라이언트는 이후 요청도 원래 주소로 보내야 합니다 |
| 303 |
See Other |
요청한 리소스를 다른 주소에서 GET으로 가져와야 할 때 서버가 직접 안내하는 응답입니다 |
| 304 |
Not Modified |
캐시 목적으로 쓰입니다. 응답이 바뀌지 않았다는 뜻이라 클라이언트는 캐시된 버전을 계속 써도 됩니다 |
| 305 |
Use Proxy |
요청한 리소스에 반드시 프록시를 거쳐 접근해야 한다는 뜻으로, 예전 HTTP 표준에서 정의됐습니다. 프록시 설정의 보안 우려로 지금은 거의 쓰이지 않습니다 |
| 306 |
Unused |
더 이상 사용되지 않는 코드로, 향후 사용을 위해 예약만 돼 있습니다. HTTP 1.1 이전 버전에서 쓰였습니다 |
| 307 |
Temporary Redirect |
302와 의미는 비슷하지만, 처음 요청에 쓴 메서드(GET, POST 등)를 두 번째 요청에서도 그대로 유지해야 한다는 점이 다릅니다 |
| 308 |
Permanent Redirect |
301과 의미는 비슷하지만, 마찬가지로 요청 메서드를 바꾸지 않아야 한다는 점이 다릅니다. 새 주소는 응답 헤더의 Location에 담깁니다 |
헷갈리기 쉬운 지점은 301·302와 307·308의 차이입니다. 숫자가 다른 이유는 요청 메서드를 유지하는지 여부입니다. 301과 302는 이후 요청에서 메서드가 바뀔 수 있고, 307과 308은 메서드를 그대로 유지합니다.
4xx, 요청 쪽에 문제가 있다는 신호
4xx는 서버가 아니라 요청 자체의 문법이나 조건에 문제가 있어 처리하지 못했다는 뜻입니다. URL 모니터링에서 4xx가 뜨면 대상 주소나 요청 설정을 먼저 점검할 대상입니다.
| 코드 |
이름 |
의미 |
| 400 |
Bad Request |
요청 문법이 잘못돼 서버가 이해할 수 없습니다 |
| 401 |
Unauthorized |
이름은 "권한 없음"이지만 실제로는 인증이 안 된 상태를 가리킵니다. 요청한 응답을 받으려면 클라이언트가 스스로를 인증해야 합니다 |
| 402 |
Payment Required |
나중에 쓰기 위해 예약된 코드입니다. 디지털 결제 시스템을 염두에 두고 만들어졌지만 실제로는 거의 쓰이지 않습니다 |
| 403 |
Forbidden |
클라이언트가 콘텐츠에 접근할 권한 자체가 없다는 뜻입니다. 401과 다른 점은, 서버가 클라이언트가 누구인지는 이미 알고 있다는 점입니다 |
| 404 |
Not Found |
서버가 요청한 리소스를 찾지 못했습니다. 브라우저에서는 알 수 없는 URL을, API에서는 종점(엔드포인트) 자체는 맞지만 그 리소스가 존재하지 않는 상황을 가리킬 수 있습니다. 웹에서 자주 마주치는 코드이기도 합니다. 인증받지 않은 클라이언트에게 리소스의 존재 자체를 숨기려고 403 대신 404를 쓰는 경우도 있습니다 |
| 405 |
Method Not Allowed |
서버가 알고 있는 메서드지만 이 리소스에는 허용하지 않은 상태입니다. 다만 GET, HEAD 같은 필수 메서드는 막을 수 없습니다 |
| 406 |
Not Acceptable |
서버가 클라이언트와 콘텐츠 협상을 진행한 뒤, 클라이언트가 요구한 조건에 맞는 콘텐츠를 찾지 못했을 때 보냅니다 |
| 407 |
Proxy Authentication Required |
401과 비슷하지만, 프록시 단계에서 인증이 필요하다는 뜻입니다 |
| 408 |
Request Timeout |
연결이 오래 유지됐는데 요청이 없을 때 서버가 보냅니다. 클라이언트가 요청을 보내지 않았는데도 서버가 408을 먼저 보내는 경우가 있는데, 사용하지 않는 연결을 정리하려는 목적입니다. 웹서핑 속도를 높이려고 HTTP 사전 연결을 쓰는 Chrome, Firefox 27+, IE 9 같은 브라우저에서 특히 자주 보이며, 이 메시지 없이 그냥 연결을 끊는 서버도 있습니다 |
| 409 |
Conflict |
요청이 서버의 현재 상태와 충돌할 때 보냅니다 |
| 410 |
Gone |
요청한 콘텐츠가 영구히 삭제됐고 대체 주소도 없다는 뜻입니다. 404와 달리 일부러, 영구히 지웠다는 의미가 강해 클라이언트가 캐시와 관련 링크를 지우기를 기대합니다. 다만 API가 리소스마다 이 코드로 삭제 여부를 강제할 필요는 없습니다 |
| 411 |
Length Required |
서버가 요구하는 Content-Length 헤더가 없는 요청을 거절하는 코드입니다 |
| 412 |
Precondition Failed |
클라이언트가 헤더에 담아 보낸 전제조건이 서버의 조건과 맞지 않습니다 |
| 413 |
Payload Too Large |
요청 본문이 서버가 정한 한도보다 큽니다. 서버는 연결을 끊거나 Retry-After 헤더로 나중에 다시 시도하라고 돌려보낼 수 있습니다 |
| 414 |
URI Too Long |
요청한 URI가 서버가 처리하기로 정한 길이보다 깁니다 |
| 415 |
Unsupported Media Type |
요청한 미디어 형식을 서버가 지원하지 않습니다 |
| 416 |
Range Not Satisfiable |
Range 헤더로 요청한 구간을 서버가 채워줄 수 없습니다. 대상 데이터 크기를 벗어난 범위를 요청했을 가능성이 있습니다 |
| 417 |
Expectation Failed |
Expect 헤더로 요청한 조건을 서버가 맞춰줄 수 없습니다 |
| 418 |
I'm a teapot |
서버가 요청받은 커피 내리기를, 찻주전자라서 거절한다는 장난으로 만들어진 코드입니다 |
| 421 |
Misdirected Request |
요청이 잘못된 서버로 전달돼, 그 서버가 응답을 만들 수 없는 상태입니다 |
| 422 |
Unprocessable Entity (WebDAV) |
요청 형식은 맞지만 그 안의 내용이 의미상 잘못돼 처리할 수 없습니다 |
| 423 |
Locked (WebDAV) |
접근하려는 리소스가 잠겨 있습니다 |
| 424 |
Failed Dependency (WebDAV) |
이전 요청이 실패해서 지금 요청도 함께 실패했습니다 |
| 425 |
Too Early |
서버가 재생 공격(같은 요청이 중간에 가로채져 다시 전송되는 것) 위험을 감수하고 싶지 않아 요청을 아직 처리하지 않았다는 뜻입니다. TLS 1.3의 0-RTT(연결 첫 왕복 전에 데이터를 먼저 보내는 방식) 데이터를 다룰 때 주로 나타납니다 |
| 426 |
Upgrade Required |
지금 프로토콜로는 처리를 거절하지만, 다른 프로토콜로 올리면 처리할 수 있다는 뜻입니다 |
| 428 |
Precondition Required |
리소스를 읽고 수정한 뒤 다시 써넣는 사이에 다른 요청이 끼어들어 상태가 바뀌는 문제(업데이트 상실)를 막기 위해, 조건부 요청을 요구하는 코드입니다 |
| 429 |
Too Many Requests |
정해진 시간 안에 너무 많은 요청을 보냈다는 뜻입니다. 이른바 요청 제한(rate limiting)입니다 |
| 431 |
Request Header Fields Too Large |
요청 헤더가 너무 커서 서버가 처리를 거절합니다 |
| 451 |
Unavailable For Legal Reasons |
정부 검열 등 법적인 사유로 차단된 리소스라는 뜻입니다 |
자주 혼동되는 부분은 401과 403의 차이, 404와 410의 차이입니다. 401은 "누구인지 증명하지 않았다", 403은 "누구인지는 알지만 접근 권한이 없다"는 뜻입니다. 404는 "지금 찾을 수 없다"는 뜻이고, 410은 "일부러 영구히 없앴고 앞으로도 없다"는 뜻이라 의미가 더 확정적입니다.
5xx, 서버 쪽에 문제가 생겼다는 신호
5xx는 요청 자체는 문제없지만 서버가 처리를 완수하지 못한 상태입니다. URL 모니터링에서 5xx는 대부분 즉시 확인이 필요한 신호로 다뤄집니다.
| 코드 |
이름 |
의미 |
| 500 |
Internal Server Error |
서버에 문제가 있다는 것만 알려줄 뿐, 구체적인 원인은 알려주지 않습니다 |
| 501 |
Not Implemented |
요청을 처리하는 데 필요한 기능을 서버가 지원하지 않습니다 |
| 502 |
Bad Gateway |
서버가 게이트웨이 역할을 하다가, 뒤에 있는 다른 서버로부터 유효하지 않은 응답을 받았습니다 |
| 503 |
Service Unavailable |
서버가 지금 요청을 처리할 준비가 안 된 상태입니다. 점검 중이거나 과부하 상황에서 자주 나타납니다. 임시 상황에 쓰는 코드라 Retry-After 헤더로 복구 예상 시간을 함께 안내하는 경우가 많습니다 |
| 504 |
Gateway Timeout |
서버가 게이트웨이 역할을 하다가, 뒤에 있는 다른 서버로부터 제 시간에 응답을 받지 못했습니다. 대개 인터넷상 서버 간 네트워크 오류나 실제 서버 쪽 문제이며, 내 컴퓨터·장치·인터넷 연결의 문제가 아닐 수 있습니다 |
| 505 |
HTTP Version Not Supported |
클라이언트가 요청한 HTTP 버전을 서버가 지원하지 않습니다. 대부분의 브라우저는 서버가 1.x 버전을 지원한다고 가정하는데, 1.0 이하의 오래된 버전은 보안·성능이 떨어져 요즘은 거의 쓰이지 않습니다. 이 오류가 뜨면 서버 소프트웨어가 지원하는 HTTP 버전을 확인해 볼 수 있습니다 |
| 506 |
Variant Also Negotiates |
서버 내부 설정 오류로, 콘텐츠 협상이 순환 참조로 이어질 때 발생합니다 |
| 507 |
Insufficient Storage (WebDAV) |
요청을 완료하는 데 필요한 표현(representation)을 저장할 공간이 서버에 부족해 처리하지 못했다는 뜻입니다 |
| 508 |
Loop Detected (WebDAV) |
서버가 요청을 처리하다 무한 루프를 감지했습니다 |
| 510 |
Not Extended |
요청을 이행하려면 추가 확장이 필요하다는 뜻입니다 |
| 511 |
Network Authentication Required |
네트워크 접속 자체를 위해 인증이 필요하다는 뜻입니다. 공용 와이파이 로그인 화면에서 종종 나타납니다 |
구분이 애매해지는 지점은 502와 504의 차이입니다. 502는 뒤쪽 서버로부터 아예 유효하지 않은 응답을 받은 경우이고, 504는 응답을 기다리다 시간 초과로 포기한 경우입니다.
마치며
실제로 URL 모니터링 알림에서 자주 마주치는 건 4xx와 5xx 두 그룹입니다. 앞자리 숫자만 봐도 문제가 요청 쪽인지 서버 쪽인지 먼저 가늠할 수 있고, 코드 하나를 더 알면 다음에 확인할 대상까지 좁힐 수 있습니다. URL 모니터링 알림에 낯선 코드가 찍혔을 때 이 글을 다시 열어 확인해 보시기 바랍니다. URL 모니터링을 아직 설정하지 않으셨다면 WhaTap URL 모니터링에서 시작할 수 있습니다.
더 읽을거리