웹사이트를 사용하다 보면 숫자로 된 메시지를 자주 만나게 된다.

200 OK
404 Not Found
500 Internal Server Error

개발자 도구의 Network 탭을 열어봐도 이런 숫자가 보이고, 웹사이트에 문제가 생겼을 때도 404나 500 같은 숫자를 확인할 수 있다.

이 숫자를 HTTP 상태 코드(Status Code)​라고 한다.

앞에서 HTTP 요청과 응답에 대해 알아봤듯이, 클라이언트가 서버에 요청을 보내면 서버는 그 요청에 대한 응답을 돌려준다.

Client
   │
   │ HTTP Request
   ▼
Server
   │
   │ HTTP Response
   ▼
Client

이때 서버는 단순히 데이터만 보내는 것이 아니라 “요청을 어떻게 처리했는지”를 나타내는 상태 코드도 함께 전달한다.

예를 들어

200

이라면 요청을 정상적으로 처리했다는 의미이고,

404

라면 요청한 리소스를 찾지 못했다는 의미다.

그렇다면 왜 굳이 세 자리 숫자를 사용하는 걸까?

이번 글에서는 HTTP 상태 코드의 분류부터 실제로 많이 사용되는 코드까지 알아보자.


HTTP 상태 코드는 왜 필요할까?

서버가 요청을 받았을 때 모든 요청을 똑같이 처리할 수는 없다.

어떤 요청은 정상적으로 처리될 수도 있고,

어떤 요청은 로그인이 필요할 수도 있다.

존재하지 않는 페이지를 요청할 수도 있고, 서버 자체에 문제가 생길 수도 있다.

이런 상황을 클라이언트에게 알려줘야 한다.

예를 들어 서버가 다음과 같은 응답을 보냈다고 생각해보자.

HTTP/1.1 404 Not Found

브라우저나 프로그램은 이 응답을 보고

“요청한 리소스를 찾지 못했구나.”

라고 판단할 수 있다.

즉 상태 코드는 서버가 요청을 처리한 결과를 정해진 숫자 체계로 알려주는 역할을 한다.


HTTP 상태 코드는 크게 5가지로 나뉜다

HTTP 상태 코드는 첫 번째 숫자에 따라 크게 다섯 종류로 구분된다.

범위의미
1xx정보 제공
2xx성공
3xx리다이렉션
4xx클라이언트 요청 오류
5xx서버 오류

이것만 기억해도 처음 보는 상태 코드의 의미를 어느 정도 추측할 수 있다.

1xx → 진행 중인 정보
2xx → 성공
3xx → 다른 처리가 필요함
4xx → 요청에 문제가 있음
5xx → 서버에 문제가 있음

예를 들어

201

을 처음 봤다고 하더라도 2xx이기 때문에 성공 계열의 응답이라는 것을 알 수 있다.


1xx 상태 코드

1xx는 Informational Response, 즉 정보성 응답이다.

클라이언트의 요청을 받았고 현재 처리 과정에 대한 추가 정보를 전달하는 용도로 사용된다.

일반적인 웹 개발에서는 2xx, 4xx, 5xx만큼 자주 접하지는 않는다.

대표적으로

100 Continue

가 있다.

클라이언트가 요청을 계속 보내도 되는 상황에서 사용될 수 있다.

예를 들어 큰 데이터를 업로드하기 전에 서버가 요청을 계속 처리할 준비가 되었는지 확인하는 과정에서 사용할 수 있다.

또 다른 예로

101 Switching Protocols

가 있는데, 서버가 클라이언트의 요청에 따라 프로토콜 전환을 승인한다는 의미다.

1xx는 기본적으로 “최종 결과가 아직 나온 것은 아니고, 처리 과정에 대한 정보가 전달되고 있다” 정도로 이해하면 된다.


2xx 상태 코드

2xx는 가장 반가운 상태 코드다.

요청이 정상적으로 처리되었다는 의미이기 때문이다.

웹 개발에서 가장 자주 보는 것은 200 OK다.

200 OK

200 OK

요청이 정상적으로 처리되었다는 의미다.

예를 들어 브라우저가

GET /index.html

을 요청했고 서버가 정상적으로 HTML을 반환했다면

HTTP/1.1 200 OK

가 응답될 수 있다.


201 Created

201 Created

요청이 성공적으로 처리되었고 새로운 리소스가 생성되었다는 의미다.

예를 들어 회원가입이나 게시글 등록 API에서 새로운 데이터를 생성했다면 201을 사용할 수 있다.

POST /users

        ↓

201 Created

다만 어떤 API가 데이터를 생성했다고 해서 반드시 201을 사용해야 한다고 단정할 수는 없다. 실제 응답 코드는 API 설계에 따라 달라질 수 있다.


204 No Content

204 No Content

요청은 정상적으로 처리되었지만 응답 Body에 전달할 콘텐츠가 없다는 의미다.

예를 들어 삭제 요청이 정상적으로 처리된 경우 사용할 수 있다.

DELETE /users/10

        ↓

204 No Content

서버에서 작업은 정상적으로 이루어졌지만 별도의 데이터를 반환할 필요가 없는 상황이다.


3xx 상태 코드

3xx는 Redirection, 즉 리다이렉션과 관련된 응답이다.

쉽게 말하면 서버가 클라이언트에게

“요청한 리소스가 다른 위치에 있으니 다른 곳을 확인해봐.”

라고 알려주는 상황이다.

대표적으로 301, 302, 304 등이 있다.


301 Moved Permanently

301 Moved Permanently

요청한 리소스가 영구적으로 다른 위치로 이동했다는 의미다.

예를 들어

http://example.com

에서

https://example.com

으로 영구적으로 변경했다고 생각해보자.

서버가 새로운 주소를 알려주면서 301 응답을 사용할 수 있다.

브라우저나 검색 엔진은 이런 정보를 바탕으로 새로운 주소를 사용할 수 있다.


302 Found

302 Found

요청한 리소스를 일시적으로 다른 위치에서 제공하는 상황에서 사용된다.

예를 들어 로그인하지 않은 사용자가 특정 페이지에 접근했을 때 로그인 페이지로 이동시키는 과정 등에서 리다이렉션이 발생할 수 있다.

다만 실제 웹 애플리케이션에서는 302뿐만 아니라 303, 307, 308 등 여러 리다이렉션 상태 코드가 존재하기 때문에 각각의 의미를 구분해서 사용할 필요가 있다.


304 Not Modified

304 Not Modified

이 상태 코드는 조금 특이하다.

서버가

“네가 가지고 있는 캐시된 데이터를 그대로 사용해도 된다.”

라는 의미로 사용할 수 있다.

예를 들어 브라우저가 이전에 이미 파일을 받아놓았다고 해보자.

브라우저가 해당 리소스가 변경되었는지 확인하는 요청을 보내고 서버가 변경되지 않았다고 판단하면 304를 반환할 수 있다.

그러면 브라우저는 기존에 가지고 있던 데이터를 다시 사용할 수 있다.

이렇게 하면 매번 같은 파일을 다시 내려받는 것을 줄일 수 있다.


4xx 상태 코드

4xx는 웹 개발에서 굉장히 자주 만나는 범위다.

기본적으로 클라이언트의 요청에 문제가 있는 상황을 나타낸다.

여기서 “클라이언트 오류”라고 해서 항상 사용자가 잘못했다는 뜻은 아니다.

잘못된 URL이나 요청 데이터, 인증 정보, 권한 문제 등 다양한 원인이 있을 수 있다.

대표적으로

400
401
403
404
405
409
429

등이 있다.


400 Bad Request

400 Bad Request

서버가 요청을 이해하거나 처리하기 어려운 잘못된 요청이라는 의미다.

예를 들어 API에 JSON 데이터를 보내야 하는데 형식이 잘못되어 있다면 400을 사용할 수 있다.

POST /users

{
    "name": "Kim",
    "email":
}

처럼 JSON 문법 자체가 잘못되어 있는 경우를 생각할 수 있다.

또는 서버가 기대하는 요청 형식과 실제 요청이 맞지 않는 경우에도 사용될 수 있다.


401 Unauthorized

401 Unauthorized

인증(Authentication)이 필요한 요청인데 적절한 인증 정보가 없거나 유효하지 않은 경우 등에 사용된다.

예를 들어 로그인한 사용자만 접근할 수 있는 API에 인증 없이 요청하는 상황을 생각할 수 있다.

GET /mypage

        ↓

401 Unauthorized

여기서 401을 단순히 “권한 없음”​이라고 외우면 헷갈리기 쉽다.

HTTP에서는 인증(Authentication)과 인가(Authorization)를 구분해서 생각하는 것이 좋다.

Authentication
→ 내가 누구인지 확인

Authorization
→ 내가 무엇을 할 수 있는지 확인

401은 주로 인증과 관련된 문제이고, 권한 부족은 보통 403과 연결된다.


403 Forbidden

403 Forbidden

서버가 요청을 이해했지만 해당 요청을 허용하지 않는 경우 사용한다.

예를 들어 로그인은 되어 있지만 관리자만 접근할 수 있는 페이지에 일반 사용자가 접근한다고 생각해보자.

로그인 완료
   ↓
관리자 페이지 요청
   ↓
403 Forbidden

401
→ 인증 정보가 문제

403
→ 요청을 이해했지만 접근을 허용하지 않음

이라는 차이를 기억하면 좋다.

실제 시스템에서는 보안상의 이유 등으로 401과 403을 다른 방식으로 설계하는 경우도 있으므로, 최종 의미는 해당 API의 문서와 구현을 확인해야 한다.


404 Not Found

아마 가장 유명한 상태 코드일 것이다.

404 Not Found

서버가 요청한 리소스를 찾지 못했다는 의미다.

예를 들어

GET /hello.html

을 요청했는데 해당 페이지가 존재하지 않는다면

404 Not Found

가 반환될 수 있다.

웹사이트에서 흔히 볼 수 있는

“페이지를 찾을 수 없습니다.”

라는 화면도 이런 상황과 연결된다.

다만 404가 반드시 “서버가 죽었다”는 의미는 아니다.

서버 자체는 정상적으로 동작하고 있지만 요청한 리소스가 없을 수도 있다.


405 Method Not Allowed

405 Method Not Allowed

해당 리소스에서는 요청한 HTTP 메서드를 허용하지 않는다는 의미다.

예를 들어 서버가

GET /users

는 허용하지만

DELETE /users

는 허용하지 않는다면 DELETE 요청에 대해 405를 반환할 수 있다.

URL은 맞을 수 있지만
HTTP Method가 잘못된 상황

에서 사용될 수 있다.


409 Conflict

409 Conflict

요청이 현재 서버의 상태와 충돌하는 경우 사용될 수 있다.

예를 들어 이미 존재하는 사용자 이름을 다시 생성하려는 경우처럼 현재 리소스 상태와 요청이 충돌하는 상황을 생각할 수 있다.

API 설계에서 데이터의 중복이나 상태 충돌을 표현할 때 사용되는 경우가 있다.


429 Too Many Requests

429 Too Many Requests

짧은 시간에 너무 많은 요청을 보냈을 때 사용된다.

예를 들어 서버가 API에 대해

1분에 100번까지만 요청 가능

이라는 제한을 두었다고 해보자.

그런데 클라이언트가 제한을 초과하면 서버는

429 Too Many Requests

를 반환할 수 있다.

이런 기능을 Rate Limiting이라고 한다.

API 서버를 운영할 때 서버 과부하를 막거나 악의적인 대량 요청을 제한하기 위해 사용된다.


5xx 상태 코드

5xx는 서버 오류를 나타낸다.

4xx가 주로 요청 측의 문제라면 5xx는 서버가 정상적으로 요청을 처리하지 못한 상황을 나타낸다.

대표적으로

500
502
503
504

등이 있다.


500 Internal Server Error

가장 대표적인 서버 오류다.

500 Internal Server Error

서버 내부에서 예상하지 못한 오류가 발생했다는 의미다.

예를 들어 서버 프로그램에서 예외가 발생했거나 처리 과정에서 문제가 생긴 경우 500을 반환할 수 있다.

Client
   │
   │ GET /users
   ▼
Server
   │
   │ 프로그램 오류
   ▼
500 Internal Server Error

개발자 입장에서는 500이 발생하면 서버 로그를 확인하는 경우가 많다.

DB 연결 문제, 코드의 예외, 잘못된 설정 등 여러 가지 원인이 있을 수 있기 때문이다.


502 Bad Gateway

502 Bad Gateway

서버가 다른 서버로부터 정상적인 응답을 받지 못했을 때 발생할 수 있다.

특히 프록시 서버나 로드 밸런서 같은 중간 서버가 있는 구조에서 자주 볼 수 있다.

Client
   ↓
Load Balancer
   ↓
Application Server
   ↓
응답 이상
   ↓
502

예를 들어 Nginx가 앞단에 있고 뒤쪽 애플리케이션 서버에 요청을 전달했는데 정상적인 응답을 받지 못한다면 502가 발생할 수 있다.


503 Service Unavailable

503 Service Unavailable

서버가 현재 요청을 처리할 수 없는 상태라는 의미다.

예를 들어

서버 점검
트래픽 과부하
일시적인 서비스 중단

등의 상황에서 사용할 수 있다.

서버 자체가 영구적으로 고장났다는 의미는 아니다.

오히려 일시적인 상태를 나타내는 경우가 많다.


504 Gateway Timeout

504 Gateway Timeout

게이트웨이 또는 프록시 역할을 하는 서버가 뒤쪽 서버의 응답을 정해진 시간 안에 받지 못했을 때 사용할 수 있다.

예를 들어

Client
  ↓
Load Balancer
  ↓
Application Server
  ↓
Database

구조에서 애플리케이션 서버의 응답이 지나치게 늦어지면 중간 서버에서 시간 초과가 발생할 수 있다.

이런 상황에서 504가 반환될 수 있다.


4xx와 5xx를 구분하는 방법

초보자 입장에서 가장 많이 헷갈리는 것이 4xx와 5xx다.

간단하게 생각하면 다음과 같다.

4xx
→ 요청을 다시 확인해볼 필요가 있음

5xx
→ 서버 쪽 상태나 처리 과정을 확인할 필요가 있음

예를 들어

404

라면 요청한 URL이나 리소스가 존재하는지 확인해야 한다.

반면

500

이라면 서버 로그나 애플리케이션 코드를 확인해야 할 가능성이 높다.

다만 실제 원인은 서비스 구현에 따라 달라질 수 있기 때문에 상태 코드만 보고 원인을 100% 확정해서는 안 된다.


HTTP 상태 코드는 브라우저만 사용하는 것이 아니다

상태 코드는 웹 브라우저에서만 사용되는 것이 아니다.

백엔드 API를 개발할 때도 매우 중요하다.

예를 들어 프론트엔드가 서버에 로그인 요청을 보냈다고 해보자.

POST /login

로그인이 성공하면

200 OK

잘못된 로그인 정보라면 API 설계에 따라

401 Unauthorized

등을 반환할 수 있다.

존재하지 않는 API를 요청하면

404 Not Found

서버에서 예외가 발생하면

500 Internal Server Error

가 반환될 수 있다.

프론트엔드 프로그램은 이런 상태 코드를 확인하고 화면에 적절한 메시지를 표시할 수 있다.

HTTP Response
      │
      ├── 200 → 정상 처리
      │
      ├── 401 → 인증 문제
      │
      ├── 403 → 접근 거부
      │
      ├── 404 → 리소스 없음
      │
      └── 500 → 서버 오류

그래서 상태 코드는 단순한 숫자가 아니라 클라이언트와 서버가 통신 결과를 약속된 방식으로 전달하는 수단이라고 볼 수 있다.


개발자 도구에서는 어떻게 확인할까?

실제 웹사이트에서 HTTP 상태 코드를 확인하고 싶다면 브라우저의 개발자 도구를 이용하면 된다.

Chrome 기준으로 개발자 도구를 열고 Network 탭을 선택한 뒤 페이지를 새로고침하면 여러 요청이 나타난다.

예를 들어

Name          Method     Status
index.html    GET        200
style.css     GET        200
script.js     GET        200
image.png     GET        404
api/users     GET        500

처럼 확인할 수 있다.

이렇게 보면 웹페이지 하나에서도 여러 HTTP 요청이 발생하고 각각의 결과에 따라 다른 상태 코드가 반환된다는 것을 알 수 있다.

특히 문제가 발생했을 때

Request URL
Request Method
Status Code
Response Headers
Response

등을 확인하면 어디에서 문제가 발생했는지 추적하는 데 도움이 된다.


자주 사용하는 상태 코드 정리

실제로 모든 상태 코드를 외울 필요는 없다.

처음에는 아래 정도만 알아도 충분하다.

코드의미자주 사용되는 상황
200OK정상적인 요청 처리
201Created리소스 생성
204No Content정상 처리, 응답 내용 없음
301Moved Permanently영구적인 주소 변경
302Found임시 리다이렉션
304Not Modified캐시된 리소스 사용 가능
400Bad Request잘못된 요청
401Unauthorized인증 필요/인증 실패
403Forbidden접근 거부
404Not Found리소스 없음
405Method Not Allowed허용되지 않은 HTTP 메서드
409Conflict현재 상태와 요청 충돌
429Too Many Requests요청 횟수 제한 초과
500Internal Server Error서버 내부 오류
502Bad Gateway중간 서버가 정상 응답을 받지 못함
503Service Unavailable일시적으로 서비스 처리 불가
504Gateway Timeout뒤쪽 서버 응답 시간 초과

마무리

HTTP 상태 코드는 서버가 클라이언트에게 “네 요청을 어떻게 처리했는지”를 알려주는 숫자​라고 이해하면 된다.

가장 먼저 기억할 것은 첫 번째 숫자다.

1xx → 정보
2xx → 성공
3xx → 리다이렉션
4xx → 클라이언트 요청 관련 문제
5xx → 서버 관련 문제

그리고 실무나 웹 개발에서 특히 자주 보는 상태 코드는

200 → 정상
201 → 생성 성공
204 → 정상 처리, 내용 없음

301 → 영구 이동
302 → 임시 이동
304 → 변경되지 않음

400 → 잘못된 요청
401 → 인증 문제
403 → 접근 거부
404 → 리소스 없음
405 → 메서드 허용 안 됨
429 → 너무 많은 요청

500 → 서버 내부 오류
502 → 게이트웨이 오류
503 → 서비스 이용 불가
504 → 게이트웨이 시간 초과

정도로 먼저 익혀두면 된다.

특히 401과 403, 404와 500, 502와 504​는 실제 개발이나 장애 상황에서 자주 접하기 때문에 차이를 알아두는 것이 좋다.

앞에서 HTTP 요청과 응답의 구조를 살펴봤다면 이제 상태 코드까지 연결해서 볼 수 있다.

Client
   │
   │ HTTP Request
   ▼
Server
   │
   │ HTTP Response
   │
   ├── 200 → 성공
   ├── 300 → 이동
   ├── 400 → 요청 문제
   └── 500 → 서버 문제
   ▼
Client

결국 HTTP 상태 코드는 웹 서버와 클라이언트가 통신 결과를 일정한 규칙으로 전달하기 위한 공통 언어라고 볼 수 있다.

다음에는 여기서 HTTPS로 넘어가서, 우리가 웹사이트 주소 앞에서 자주 보는 https://가 HTTP와 무엇이 다르고 왜 필요한지 살펴보면 HTTP 시리즈가 자연스럽게 이어진다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다

글쓴이

rjsan46@koreabites.com

관련 게시물

웹 브라우저에 주소를 입력하면 일어나는 일

웹 브라우저 주소창에 웹사이트 주소를 입력하고 엔터를 누르면 바로 화면이 나타나는 것처럼 보인다. 하지만 실제로는 그 짧은 순간에 꽤 많은 일이 일어난다....

모두 읽어보기

소켓이란 무엇일까? 프로그램과 네트워크를 연결하는 통로

네트워크를 공부하다 보면 IP 주소와 포트 번호라는 말을 계속 만나게 된다. IP 주소는 어떤 컴퓨터와 통신할 것인지 구분하고, 포트 번호는 그 컴퓨터에서...

모두 읽어보기

쿠키와 세션은 어떻게 다를까?

웹사이트를 이용하다 보면 한 번 로그인한 뒤 다른 페이지로 이동해도 로그인 상태가 계속 유지되는 것을 볼 수 있다. 예를 들어 쇼핑몰에 로그인한...

모두 읽어보기

SSL과 TLS는 어떤 역할을 할까?

앞에서 HTTPS가 HTTP보다 안전한 이유를 살펴봤다. HTTPS는 단순히 HTTP 자체가 더 안전하게 만들어진 프로토콜이 아니라, HTTP 통신에 TLS라는 보안 계층을 적용한 것이라고...

모두 읽어보기

포트 번호로 네트워크 서비스를 구분하는 방법

컴퓨터가 네트워크를 통해 다른 컴퓨터와 통신할 때 가장 먼저 떠오르는 것이 IP 주소다. 예를 들어 어떤 서버의 IP 주소가 192.168.0.10이라고 해보자. 그런데...

모두 읽어보기

HTTPS는 HTTP보다 무엇이 안전할까?

인터넷에서 웹사이트에 접속하다 보면 주소창에 http://가 붙어 있는 경우도 있고 https://가 붙어 있는 경우도 있다. 요즘은 대부분의 웹사이트가 HTTPS를 사용하기 때문에 사실상...

모두 읽어보기