- 0
- 311 words
웹사이트를 사용하다 보면 숫자로 된 메시지를 자주 만나게 된다.
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
등을 확인하면 어디에서 문제가 발생했는지 추적하는 데 도움이 된다.
자주 사용하는 상태 코드 정리
실제로 모든 상태 코드를 외울 필요는 없다.
처음에는 아래 정도만 알아도 충분하다.
| 코드 | 의미 | 자주 사용되는 상황 |
|---|---|---|
| 200 | OK | 정상적인 요청 처리 |
| 201 | Created | 리소스 생성 |
| 204 | No Content | 정상 처리, 응답 내용 없음 |
| 301 | Moved Permanently | 영구적인 주소 변경 |
| 302 | Found | 임시 리다이렉션 |
| 304 | Not Modified | 캐시된 리소스 사용 가능 |
| 400 | Bad Request | 잘못된 요청 |
| 401 | Unauthorized | 인증 필요/인증 실패 |
| 403 | Forbidden | 접근 거부 |
| 404 | Not Found | 리소스 없음 |
| 405 | Method Not Allowed | 허용되지 않은 HTTP 메서드 |
| 409 | Conflict | 현재 상태와 요청 충돌 |
| 429 | Too Many Requests | 요청 횟수 제한 초과 |
| 500 | Internal Server Error | 서버 내부 오류 |
| 502 | Bad Gateway | 중간 서버가 정상 응답을 받지 못함 |
| 503 | Service Unavailable | 일시적으로 서비스 처리 불가 |
| 504 | Gateway 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 시리즈가 자연스럽게 이어진다.