HTTP 상태 코드 404, 500, 502, 503 의미 정리
상태 코드 분류 체계와 자주 마주치는 오류의 실제 원인, 401과 403, 502와 504의 차이를 정리했습니다.
첫 자리만 봐도 절반은 좁혀진다
HTTP 상태 코드는 세 자리 숫자이고 첫 자리가 분류를 나타냅니다.
2xx는 성공, 3xx는 리다이렉션, 4xx는 요청을 보낸 쪽의 문제, 5xx는 서버 쪽의 문제입니다. 장애 대응에서 이 구분이 중요한 이유는 어디를 먼저 봐야 할지 결정해 주기 때문입니다.
4xx가 나오면 클라이언트가 보낸 주소, 헤더, 본문, 인증 정보를 확인해야 합니다. 5xx가 나오면 요청은 제대로 도착했으므로 서버 로그와 인프라를 봐야 합니다. 이 구분만 지켜도 엉뚱한 곳을 뒤지는 시간을 크게 줄일 수 있습니다.
404와 403, 그리고 401
404 Not Found는 요청한 리소스가 없다는 뜻입니다. 주소 오타, 삭제된 데이터, 라우팅 설정 누락이 흔한 원인입니다. 정적 파일이라면 배포 과정에서 파일이 빠졌을 수도 있습니다.
401 Unauthorized는 이름과 달리 인증(authentication) 문제입니다. 토큰이 없거나 만료됐거나 형식이 틀려서 서버가 요청자를 식별하지 못하는 상태입니다. 로그인하거나 토큰을 갱신하면 해결됩니다.
403 Forbidden은 인가(authorization) 문제입니다. 누구인지는 확인했지만 그 리소스에 접근할 권한이 없는 상태입니다. 로그인해도 해결되지 않고 권한을 부여받아야 합니다.
참고로 보안상의 이유로 403 대신 404를 반환하는 서비스도 있습니다. 리소스의 존재 여부 자체를 감추기 위해서입니다.
500번대는 어디서 발생했는지가 중요하다
500 Internal Server Error는 애플리케이션 코드에서 처리되지 않은 예외가 발생했다는 뜻입니다. 서버 로그에 스택 트레이스가 남아 있을 가능성이 높습니다.
502 Bad Gateway와 504 Gateway Timeout은 성격이 다릅니다. 둘 다 리버스 프록시나 로드밸런서가 반환하는 코드로, 애플리케이션 자체가 아니라 그 앞단에서 발생합니다.
502는 상위 서버가 잘못된 응답을 주었거나 아예 연결되지 않은 경우입니다. 애플리케이션 프로세스가 죽었거나, 포트 설정이 틀렸거나, 배포 중에 잠시 서버가 없는 상황에서 자주 나옵니다.
504는 연결은 됐지만 정해진 시간 안에 응답이 오지 않은 경우입니다. 무거운 쿼리, 외부 API 지연, 무한 루프가 원인일 수 있습니다. 프록시의 타임아웃 값만 늘리는 것은 근본 해결이 아니므로 실제 처리 시간을 먼저 확인해야 합니다.
503 Service Unavailable은 서버가 일시적으로 요청을 처리할 수 없는 상태입니다. 점검 중이거나 과부하로 요청을 거절하는 경우이며, Retry-After 헤더로 언제 다시 시도할지 알려줄 수 있습니다.
API를 설계할 때의 기준
직접 API를 만들 때는 아래 기준이 도움이 됩니다.
- 성공했지만 반환할 내용이 없으면 204 No Content를 사용합니다.
- 리소스를 새로 만들었다면 201 Created와 함께 Location 헤더로 위치를 알려줍니다.
- 입력값 형식이 틀렸으면 400, 인증이 없으면 401, 권한이 없으면 403, 대상이 없으면 404를 반환합니다.
- 검증에는 통과했지만 비즈니스 규칙에 어긋나면 422 Unprocessable Entity를 쓰는 경우가 많습니다.
- 요청 빈도를 제한한다면 429 Too Many Requests와 Retry-After 헤더를 함께 반환합니다.
- 오류인데도 200을 반환하고 본문에 실패를 담는 설계는 피하는 것이 좋습니다. 모니터링과 캐시가 정상 응답으로 오해합니다.