🌐 HTTP 상태 코드 조회·설명
404, 403, 500, 502 같은 HTTP 상태 코드의 뜻과 흔한 원인, 대응 방법을 번호나 단어로 바로 찾아봐요.
사용법
- 검색칸에 404 같은 번호나 timeout, 권한 같은 단어를 넣으세요. 번호는 앞부분만(예: 30) 넣어도 돼요.
- 분류 선택으로 1xx~5xx 중 한 묶음만 볼 수 있어요.
- 각 코드 아래에 뜻과 흔한 원인·확인할 곳이 나와요. 비표준 코드(Cloudflare, nginx)는 따로 표시돼요.
상태 코드는 앞자리로 읽어요
HTTP 상태 코드는 세 자리 숫자이고 첫 자리가 종류를 뜻해요. 1xx는 처리 중인 정보, 2xx는 성공, 3xx는 다른 곳으로 이동, 4xx는 요청한 쪽(클라이언트)의 잘못, 5xx는 서버 쪽 잘못이에요. 뜻을 모르는 코드가 나와도 첫 자리만 보면 "내가 고칠 문제인가, 서버 문제인가"를 바로 알 수 있어요. 이 기준은 HTTP 표준(RFC 9110)에 정의되어 있고, 자세한 번호 목록은 IANA 상태 코드 등록부에서 관리해요.
자주 보는 코드 한눈에
| 코드 | 한 줄 의미 | 먼저 확인할 것 |
|---|---|---|
| 200 | 성공 | 정상이에요. |
| 301 / 302 | 영구 / 임시 이동 | 주소 통일은 301, 임시 이동은 302(또는 307). |
| 304 | 바뀐 게 없음 | 브라우저 캐시를 쓰는 정상 동작이에요. |
| 400 | 잘못된 요청 | JSON 문법, 필수 값, 헤더를 확인하세요. |
| 401 | 인증 필요 | 로그인·토큰이 없거나 만료됐어요. |
| 403 | 권한 없음 | 로그인해도 접근이 금지된 자원이에요. |
| 404 | 없는 주소 | URL 오타, 삭제된 페이지, 깨진 링크. |
| 429 | 요청이 너무 많음 | Retry-After만큼 쉬었다가 재시도하세요. |
| 500 | 서버 내부 오류 | 서버 로그의 오류 메시지를 보세요. |
| 502 / 504 | 상위 서버 응답 불량 / 지연 | nginx 뒤의 앱 서버 상태와 타임아웃. |
| 503 | 일시적 사용 불가 | 과부하 또는 점검 중이에요. |
헷갈리는 코드 쌍 구분하기
401과 403
401은 이름이 Unauthorized(권한 없음)지만 실제 뜻은 "누구인지 모르겠다, 로그인하라"예요. 로그인 정보를 다시 보내면 해결될 수 있어요. 403은 "누군지는 알지만 이 자원은 안 된다"예요. 관리자 페이지에 일반 계정으로 들어갔을 때처럼, 다시 로그인해도 같은 결과예요.
301과 302 (그리고 307·308)
301은 영구 이동이라 검색 엔진이 새 주소로 순위를 옮겨요. 302는 임시 이동이라 원래 주소를 계속 색인에 둬요. 사이트 주소를 바꿀 때 302를 쓰면 이전 주소가 오래 남을 수 있어요. 307과 308은 각각 302와 301처럼 임시·영구 이동이지만, POST를 GET으로 바꾸지 않고 그대로 유지한다는 점이 달라요. 폼 제출을 리다이렉트할 때 중요해요.
404와 410
404는 "지금은 없다", 410은 "영구히 없어졌고 돌아오지 않는다"예요. 검색 엔진은 410을 더 빨리 색인에서 지우는 경향이 있어요. 지운 글을 확실히 내리고 싶으면 410을 쓸 수 있지만 대부분의 사이트는 404로도 충분해요.
500, 502, 503, 504
500은 서버 안에서 코드가 터졌다는 뜻, 502는 중간 서버(프록시)가 뒤쪽 서버에서 이상한 응답을 받았다는 뜻, 503은 서버가 일부러/과부하로 요청을 받지 못한다는 뜻, 504는 뒤쪽 서버가 너무 오래 걸려서 프록시가 포기했다는 뜻이에요. 웹 서버(nginx)와 앱 서버(Node·PHP·Python)를 나눠 쓰는 환경에서는 앱이 죽으면 502, 앱이 멈추면 504가 흔해요.
검색 엔진(SEO) 관점에서
- 200인 페이지만 정상적으로 색인돼요. 내용이 없는데 200을 돌려주는 "소프트 404"는 검색 품질에 좋지 않아요. 없는 페이지에는 진짜 404를 돌려주세요.
- 301은 순위 신호를 새 주소로 넘기는 정석이에요. 주소를 바꾸면 301로 연결하고 사이트맵과 내부 링크도 새 주소로 고치세요.
- 503은 "잠시 점검 중"을 알리는 데 맞는 코드예요. 점검 페이지를 200으로 보여 주면 점검 문구가 색인될 수 있어요.
- 5xx가 길게 이어지면 크롤러가 방문을 줄이고 페이지가 색인에서 빠질 수 있어요.
- 429로 크롤러를 막으면 방문 빈도가 줄어요. 의도한 게 아니라면 요청 제한 설정을 확인하세요.
개발할 때 코드 고르는 기준
- 새 자원을 만들었으면 201, 응답 본문 없이 성공이면 204, 처리를 접수만 했으면 202.
- 입력값 검증에 실패했으면 400 또는 422. 형식이 깨졌으면 400, 형식은 맞는데 내용이 규칙에 어긋나면 422를 많이 써요.
- 로그인이 안 됐으면 401, 로그인했지만 권한이 없으면 403, 자원이 없으면 404.
- 중복 생성이나 버전 충돌이면 409, 요청 한도 초과면 429.
- 예상 못 한 서버 예외는 500, 의존 서비스(DB·외부 API) 장애는 502·503·504.
팀이나 API 문서마다 세부 규칙이 다를 수 있으니, 사내 규약이 있으면 그것을 우선하세요. 클라이언트는 번호의 첫 자리(2xx 성공, 4xx 요청 오류)로 먼저 분기하고, 구체적인 번호는 보조로 쓰는 편이 안전해요.
사이트 점검 때 확인 방법
브라우저 개발자도구(F12) → 네트워크 탭에서 요청마다 상태 코드를 볼 수 있어요. 터미널에서는 curl -I https://example.com으로 응답 헤더와 상태 줄만 확인할 수 있고, curl -sL -o /dev/null -w '%{http_code}' 주소는 리다이렉트를 따라간 뒤 최종 코드만 출력해요. 사이트가 Cloudflare 같은 CDN 뒤에 있으면 CDN이 보여 주는 코드(52x)와 원본 서버가 낸 코드가 다를 수 있어서 둘을 나눠 확인하세요. 주소 인코딩 문제로 404가 나는 경우는 URL 인코더로 주소를 확인해 보세요.
표준 코드 전체 목록
아래 표는 이 사전에 들어 있는 코드를 분류별로 정리한 것이에요. 비표준 코드(499·520~526)는 해당 서비스의 문서에만 정의돼 있어요.
1xx 정보
| 코드 | 이름 | 뜻 |
|---|---|---|
| 100 | Continue | 요청 헤더까지 잘 받았으니 본문을 계속 보내라는 중간 응답이에요. |
| 101 | Switching Protocols | 프로토콜을 바꾸자는 요청을 받아들였어요. |
| 102 | Processing | 요청을 받아 처리 중이니 기다리라는 응답이에요. |
| 103 | Early Hints | 최종 응답 전에 미리 읽어 올 자원 목록(Link 헤더)을 먼저 보내요. |
2xx 성공
| 코드 | 이름 | 뜻 |
|---|---|---|
| 200 | OK | 요청이 성공했어요. |
| 201 | Created | 요청이 성공해서 새 자원이 만들어졌어요. |
| 202 | Accepted | 요청은 접수했지만 처리는 아직 안 끝났어요. |
| 203 | Non-Authoritative Information | 프록시가 원본 응답을 일부 바꿔서 전달했어요. |
| 204 | No Content | 성공했지만 돌려줄 본문이 없어요. |
| 205 | Reset Content | 성공했으니 입력 화면(폼)을 초기화하라는 뜻이에요. |
| 206 | Partial Content | 요청한 범위(Range)의 일부만 보내요. |
| 207 | Multi-Status | 여러 자원에 대한 결과가 한 응답에 들어 있어요. |
| 208 | Already Reported | 같은 내용을 앞에서 이미 알려 줬으니 생략해요. |
| 226 | IM Used | 서버가 변경분(delta)만 적용한 결과를 보내요. |
3xx 리다이렉션
| 코드 | 이름 | 뜻 |
|---|---|---|
| 300 | Multiple Choices | 요청에 맞는 선택지가 여러 개예요. |
| 301 | Moved Permanently | 주소가 영구적으로 바뀌었어요. |
| 302 | Found | 임시로 다른 주소에 있어요. |
| 303 | See Other | 다른 주소를 GET으로 다시 요청하라는 뜻이에요. |
| 304 | Not Modified | 바뀐 게 없으니 저장해 둔 사본을 쓰세요. |
| 305 | Use Proxy | 지정한 프록시를 통해 접근하라는 뜻이었어요. |
| 307 | Temporary Redirect | 임시로 다른 주소예요. 요청 방법(POST 등)을 그대로 유지해요. |
| 308 | Permanent Redirect | 영구 이동이에요. 요청 방법을 그대로 유지해요. |
4xx 클라이언트 오류
| 코드 | 이름 | 뜻 |
|---|---|---|
| 400 | Bad Request | 요청 형식이 잘못돼 서버가 이해하지 못했어요. |
| 401 | Unauthorized | 인증이 필요해요(로그인 안 됨, 토큰 만료·오류). |
| 402 | Payment Required | 결제가 필요해요(예약된 코드). |
| 403 | Forbidden | 누군지는 알지만 접근 권한이 없어요. |
| 404 | Not Found | 요청한 주소에 자원이 없어요. |
| 405 | Method Not Allowed | 이 주소에서는 그 요청 방법(GET/POST 등)을 못 써요. |
| 406 | Not Acceptable | 요청이 원하는 형식(Accept)으로는 줄 수 없어요. |
| 407 | Proxy Authentication Required | 프록시 인증이 필요해요. |
| 408 | Request Timeout | 서버가 요청이 다 오기를 기다리다 시간이 지났어요. |
| 409 | Conflict | 자원의 현재 상태와 충돌해서 처리할 수 없어요. |
| 410 | Gone | 자원이 영구적으로 사라졌고 새 주소도 없어요. |
| 411 | Length Required | Content-Length 헤더가 꼭 필요해요. |
| 412 | Precondition Failed | 요청에 건 조건(If-Match 등)이 맞지 않아요. |
| 413 | Content Too Large | 요청 본문이 서버가 허용하는 크기를 넘었어요. |
| 414 | URI Too Long | 주소(URL)가 너무 길어요. |
| 415 | Unsupported Media Type | 서버가 지원하지 않는 형식(Content-Type)으로 보냈어요. |
| 416 | Range Not Satisfiable | 요청한 범위(Range)가 자원 크기를 벗어났어요. |
| 417 | Expectation Failed | Expect 헤더의 기대를 서버가 만족시킬 수 없어요. |
| 418 | I'm a teapot | 저는 찻주전자라 커피를 못 끓여요. 만우절 규격(RFC 2324)이에요. |
| 421 | Misdirected Request | 이 서버가 응답할 수 없는 곳으로 요청이 잘못 보내졌어요. |
| 422 | Unprocessable Content | 형식은 맞지만 내용에 의미 오류가 있어 처리할 수 없어요. |
| 423 | Locked | 자원이 잠겨 있어요. |
| 424 | Failed Dependency | 앞선 요청이 실패해서 이 요청도 실패했어요. |
| 425 | Too Early | 재전송될 수 있는 요청이라 처리를 미뤄요. |
| 426 | Upgrade Required | 더 높은 프로토콜로 올려서 다시 요청하세요. |
| 428 | Precondition Required | 조건부 요청(If-Match 등)이 필수예요. |
| 429 | Too Many Requests | 짧은 시간에 요청이 너무 많았어요. |
| 431 | Request Header Fields Too Large | 요청 헤더가 너무 커요. |
| 451 | Unavailable For Legal Reasons | 법적인 이유로 접근이 막혀 있어요. |
| 499 | Client Closed Request | 응답이 오기 전에 클라이언트가 연결을 끊었어요. |
5xx 서버 오류
| 코드 | 이름 | 뜻 |
|---|---|---|
| 500 | Internal Server Error | 서버 내부에서 예상치 못한 오류가 났어요. |
| 501 | Not Implemented | 서버가 그 요청 방법을 지원하지 않아요. |
| 502 | Bad Gateway | 게이트웨이·프록시가 상위 서버에서 잘못된 응답을 받았어요. |
| 503 | Service Unavailable | 서버가 과부하이거나 점검 중이라 지금은 처리할 수 없어요. |
| 504 | Gateway Timeout | 게이트웨이가 상위 서버의 응답을 기다리다 시간이 지났어요. |
| 505 | HTTP Version Not Supported | 서버가 요청의 HTTP 버전을 지원하지 않아요. |
| 506 | Variant Also Negotiates | 서버 설정 오류로 내용 협상이 순환돼요. |
| 507 | Insufficient Storage | 서버 저장 공간이 부족해서 요청을 처리할 수 없어요. |
| 508 | Loop Detected | 처리 중 무한 루프가 감지됐어요. |
| 510 | Not Extended | 요청에 필요한 확장이 없어요. |
| 511 | Network Authentication Required | 네트워크 접속 인증이 필요해요. |
| 520 | Web Server Returned an Unknown Error | 원본 서버가 Cloudflare에 예상치 못한 응답을 줬어요. |
| 521 | Web Server Is Down | 원본 서버가 연결을 거부했어요. |
| 522 | Connection Timed Out | Cloudflare가 원본 서버와 연결하는 데 시간이 지났어요. |
| 523 | Origin Is Unreachable | Cloudflare가 원본 서버에 도달할 수 없어요. |
| 524 | A Timeout Occurred | 연결은 됐지만 원본 서버가 제때 응답하지 않았어요. |
| 525 | SSL Handshake Failed | Cloudflare와 원본 서버 사이 SSL 핸드셰이크가 실패했어요. |
| 526 | Invalid SSL Certificate | 원본 서버의 SSL 인증서가 유효하지 않아요. |
출처: RFC 9110(HTTP Semantics), IANA HTTP Status Code Registry, 각 상태 코드를 정의한 RFC, Cloudflare·nginx 공식 문서. 일부 이름은 RFC 9110에서 바뀌었어요(413 Content Too Large, 422 Unprocessable Content, 416 Range Not Satisfiable). 서비스마다 같은 코드를 약간 다르게 쓸 수 있어요.