메뉴
← 기술 블로그
글자 크기
Infrastructure2026.08.19

502가 떴다 — HTTP 상태 코드로 장애 원인 읽는 법

상태 코드는 외우는 게 아니라 읽는 겁니다. 같은 “서버 에러”도 502, 503, 504는 원인과 대응이 전혀 다릅니다.

“502 떴어요. 서버 죽은 건가요?”

운영팀에서 가장 많이 듣는 질문입니다. 그런데 502는 “서버가 죽었다”는 뜻이 아닙니다. 프록시가 백엔드한테 물어봤는데 이상한 답을 받았다는 뜻입니다. 서버가 죽었으면 503이고, 답이 늦으면 504입니다. 이 차이를 모르면 장애 대응 시간이 두 배로 늘어납니다.

HTTP 상태 코드는 서버가 클라이언트에게 보내는3자리 숫자 응답입니다.

1xx부터 5xx까지 다섯 종류인데,실무에서 진짜 중요한 건 그중 일부입니다.전체를 외울 필요 없이,장애 상황에서 “이 코드가 뜨면 어디를 봐야 하는가”를 아는 게 핵심입니다.

1xx — 아직 처리 중

실무에서 직접 만날 일은 거의 없습니다. 브라우저와 서버 사이에서 자동으로 처리되기 때문입니다.

100
Continue — 요청 헤더를 받았으니 본문을 보내라. 대용량 파일 업로드 시 서버가 먼저 거부할 수 있게 해주는 메커니즘.
101
Switching Protocols — HTTP에서 WebSocket으로 전환할 때. 채팅, 실시간 알림 구현 시 한 번은 지나가는 코드.

유일하게 기억할 것: WebSocket 연결이 안 될 때 101이 오는지 확인하세요. 101이 안 오면 프록시가 Upgrade 헤더를 먹고 있을 가능성이 높습니다.

2xx — 성공

요청이 정상 처리되었다는 뜻입니다. 대부분 200만 쓰지만, API를 설계한다면 구분해서 써야 합니다.

200
OK — 요청 성공. GET으로 데이터를 조회했을 때의 기본 응답.
201
Created — 리소스 생성 성공. POST로 데이터를 만들었을 때 200 대신 이걸 써야 합니다.
204
No Content — 성공했지만 돌려줄 본문이 없음. DELETE 성공 시 적합. 200에 빈 바디를 보내는 것보다 의미가 명확합니다.

흔한 실수: 200으로 에러를 보내는 API

상태 코드는 200인데 바디에 { "success": false, "error": "..." }를 보내는 패턴. 모니터링 도구가 에러를 잡지 못하고, 프록시 캐시가 에러 응답을 캐싱하는 사고가 발생합니다. 에러는 4xx/5xx로 보내세요.

3xx — 리다이렉트

요청한 리소스가 다른 곳에 있다는 뜻입니다. SEO와 직접 연결되기 때문에 웹 서비스라면 정확히 구분해야 합니다.

301
Moved Permanently — 영구 이동. 검색 엔진이 새 URL로 인덱스를 옮깁니다. 도메인 변경, URL 구조 개편 시 사용.
302
Found (임시 이동) — 임시 이동. 검색 엔진이 원래 URL을 유지합니다. 점검 페이지, A/B 테스트에 적합.
304
Not Modified — 캐시된 버전을 그대로 쓰라는 뜻. 본문 없이 헤더만 옵니다. 브라우저 캐싱의 핵심.
307
Temporary Redirect — 302와 같은 임시 이동이지만, HTTP 메서드를 유지합니다. POST 요청을 리다이렉트할 때 302를 쓰면 GET으로 바뀌는 문제가 있어서, API에서는 307이 안전합니다.
308
Permanent Redirect — 301과 같은 영구 이동이지만, HTTP 메서드를 유지합니다. API 엔드포인트 영구 이전 시 301 대신 사용.

301 vs 308, 302 vs 307 — 핵심 차이

301/302는 리다이렉트 시 POST를 GET으로 바꿀 수 있습니다(브라우저 구현에 따라 다름). 308/307은 원래 메서드를 반드시 유지합니다. 웹 페이지 리다이렉트는 301/302, API 리다이렉트는 308/307이 안전합니다.

4xx — 클라이언트 잘못

요청 자체에 문제가 있다는 뜻입니다. 서버는 정상인데 클라이언트가 잘못 보냈을 때 뜹니다. 가장 혼동이 많은 구간입니다.

400
Bad Request — 요청 형식이 잘못됨. JSON 파싱 실패, 필수 파라미터 누락, 유효성 검증 실패 등.
401
Unauthorized — 인증 안 됨. 토큰이 없거나 만료됨. 이름이 헷갈리지만 “인증(Authentication)” 실패입니다.
403
Forbidden — 인가 안 됨. 인증은 됐지만 권한이 없음. “인가(Authorization)” 실패입니다.
404
Not Found — 리소스가 없음. URL 오타일 수도 있고, 보안 목적으로 403 대신 404를 내리기도 합니다(리소스 존재 여부를 숨기기 위해).
405
Method Not Allowed — GET만 허용된 엔드포인트에 POST를 보냈을 때. CORS preflight(OPTIONS)가 막힐 때도 종종 보입니다.
408
Request Timeout — 클라이언트가 요청을 너무 느리게 보냄. 서버가 기다리다 끊은 것. 504(서버가 느린 것)와 반대.
409
Conflict — 리소스 충돌. 이미 존재하는 사용자명으로 가입 시도, 동시 수정 충돌 등.
422
Unprocessable Entity — 문법은 맞지만 의미가 틀림. JSON 형식은 OK인데 “나이: -5”처럼 비즈니스 규칙 위반. 400과의 차이는 미묘하지만, 400은 파싱 실패, 422는 검증 실패.
429
Too Many Requests — Rate Limit 초과. Retry-After 헤더를 확인하세요. API 연동 시 반드시 처리해야 하는 코드.

401 vs 403 — 면접에서도 자주 나오는 질문

401은 “너 누구야?”(인증 실패), 403은 “너인 건 알겠는데 안 돼”(인가 실패). 이름이 Unauthorized라서 헷갈리지만, 401은 Authentication, 403은 Authorization입니다. 로그인 안 한 사용자 → 401, 일반 유저가 관리자 페이지 접근 → 403.

5xx — 서버/인프라 장애

이 글의 핵심입니다. 5xx가 뜨면 “서버 에러”로 뭉뚱그리지 말고, 코드별로 봐야 할 곳이 다릅니다.

500Internal Server Error
어디를 봐야 하나: 애플리케이션 로그 (stderr, exception)
첫 번째 조치: 최근 배포 확인, 에러 로그에서 스택트레이스 찾기
502Bad Gateway
어디를 봐야 하나: 프록시/로드밸런서 로그 (Nginx upstream)
첫 번째 조치: 백엔드 프로세스 상태 확인, 포트 바인딩 확인
503Service Unavailable
어디를 봐야 하나: 서버 리소스 (CPU, 메모리, 커넥션 풀)
첫 번째 조치: 배포 중인지 확인, 오토스케일링 상태 확인
504Gateway Timeout
어디를 봐야 하나: 프록시 timeout 설정 + 백엔드 응답 시간
첫 번째 조치: slow query 로그, 외부 API 응답 시간 확인

500 Internal Server Error — 코드 버그

가장 일반적인 서버 에러입니다.
서버 애플리케이션 내부에서 예외가 발생했다는 뜻입니다.

NullPointerException, unhandled promise rejection, 잘못된 SQL 쿼리 등.
답은 항상 애플리케이션 로그에 있습니다.

500이 간헐적으로 뜬다면특정 입력 조건에서만 터지는 엣지 케이스일 가능성이 높습니다.재현 조건을 찾는 게 핵심입니다.

502 Bad Gateway — 프록시가 이상한 응답을 받음

Nginx나 로드밸런서 같은 리버스 프록시가백엔드 서버에 요청을 전달했는데,백엔드가 비정상적인 응답을 돌려줬거나연결 자체가 끊겼을 때 발생합니다.

Nginx 에러 로그에서 502 원인 확인
# 가장 먼저 볼 곳
tail -f /var/log/nginx/error.log | grep upstream

# 자주 보이는 패턴
upstream prematurely closed connection  → 백엔드가 응답 도중 연결을 끊음
connect() failed (111: Connection refused)  → 백엔드 프로세스가 안 떠 있음
no live upstreams  → upstream 그룹의 모든 서버가 다운

502의 대부분은 백엔드 프로세스가 죽었거나, 배포 중에 잠깐 내려간 경우입니다. 프로세스 매니저(PM2, systemd)로 백엔드 상태를 확인하세요.

503 Service Unavailable — 지금은 안 됨

서버가 일시적으로 요청을 처리할 수 없는 상태입니다.서버가 살아 있긴 한데 과부하이거나,의도적으로 요청을 거부하는 것입니다.

503이 뜨는 일반적인 상황은 세 가지입니다.

첫째, 롤링 배포 중에 인스턴스가 준비 안 된 경우.
둘째, DB 커넥션 풀이 가득 찬 경우.
셋째, 서킷 브레이커가 열린 경우.

Retry-After 헤더가 있다면그 시간만큼 기다린 후 재시도하면 됩니다.

504 Gateway Timeout — 백엔드가 시간 안에 응답 안 함

프록시가 백엔드에 요청을 보냈는데, 설정된 시간 내에 응답이 오지 않은 경우입니다. 502와 달리 연결은 됐지만 응답이 너무 느린 것입니다.

Nginx proxy timeout 설정 확인
# /etc/nginx/nginx.conf 또는 site config
proxy_connect_timeout  5s;   # 백엔드 연결 타임아웃
proxy_send_timeout     30s;  # 요청 전송 타임아웃
proxy_read_timeout     60s;  # 응답 대기 타임아웃 ← 504의 직접 원인

# 504가 자주 뜬다면
# 1. slow query가 있는지 DB 로그 확인
# 2. 외부 API 호출이 있는지 확인
# 3. proxy_read_timeout을 무작정 늘리지 말고 원인을 찾을 것

리버스 프록시 뒤에서의 상태 코드

대부분의 프로덕션 환경은클라이언트 → 프록시(Nginx, HAProxy, ALB) → 백엔드 구조입니다.

이 구조에서는 같은 상태 코드라도어디서 생성되었느냐에 따라 의미가 달라집니다.

백엔드가 보낸 4xx/5xx

프록시는 백엔드의 응답을 그대로 전달합니다. Nginx 액세스 로그에 상태 코드가 찍히고, 에러 로그에는 아무것도 없습니다.

프록시가 생성한 502/503/504

프록시 자체가 만든 에러입니다. Nginx 에러 로그에 upstream 관련 메시지가 찍힙니다. 백엔드 로그에는 아무것도 없을 수 있습니다.

로드밸런서(ALB/NLB)가 생성한 5xx

AWS ALB의 경우 502/503/504를 자체 생성합니다. CloudWatch의 ELB 5XX Count와 Target 5XX Count를 분리해서 봐야 합니다. ELB 5XX는 로드밸런서 문제, Target 5XX는 백엔드 문제.

장애 대응 첫 30초의 판단

5xx가 뜨면 가장 먼저 “프록시가 생성한 건지, 백엔드가 보낸 건지”를 확인하세요. Nginx라면 error.log에 upstream 키워드가 있는지, AWS라면 ELB 5XX vs Target 5XX를 봅니다. 이 한 가지 판단이 이후 조치의 방향을 결정합니다.

API 설계할 때 자주 틀리는 것들

1. 모든 응답을 200으로 보내기

에러도 200에 담아 보내면 모니터링 도구가 에러를 감지하지 못합니다. CDN이나 프록시가 에러 응답을 캐싱하는 사고도 발생합니다. HTTP 상태 코드는 기계가 읽는 것이고, 바디의 메시지는 사람이 읽는 것입니다. 둘 다 정확해야 합니다.

2. DELETE 성공 시 200 + 빈 바디

삭제 성공이면 204 No Content가 적절합니다. 200에 빈 바디를 보내면 클라이언트가 JSON 파싱을 시도하다 에러가 날 수 있습니다. 삭제된 리소스 정보를 돌려주고 싶다면 200 + 바디, 아니면 204.

3. 인증/인가를 구분 안 하고 모두 401

토큰이 없으면 401, 토큰은 있지만 권한이 부족하면 403. 프론트엔드에서 401이면 로그인 페이지로, 403이면 권한 안내 페이지로 보내야 합니다. 둘 다 401로 보내면 UX가 깨집니다.

4. 404를 남용하기

존재하지 않는 리소스에 404를 보내는 건 맞지만, 보안상 리소스 존재 여부를 숨기고 싶다면(예: 다른 사용자의 비공개 게시글) 403 대신 의도적으로 404를 보내기도 합니다. GitHub이 이 패턴을 씁니다. 다만 API 문서에 명시해야 디버깅할 때 혼동이 없습니다.

장애 대응 빠른 참조표

코드첫 번째로 볼 곳
400요청 형식 오류요청 바디/파라미터
401인증 실패토큰 만료/누락
403권한 없음RBAC/ACL 설정
404리소스 없음URL 경로, 라우팅 설정
429요청 과다Rate Limit 정책, Retry-After
500서버 내부 에러애플리케이션 에러 로그
502백엔드 비정상 응답프록시 error.log, 백엔드 프로세스
503서비스 불가CPU/메모리, 커넥션 풀, 배포 상태
504응답 지연proxy_read_timeout, slow query

HTTP 상태 코드는 서버가 보내는 진단서입니다.

코드를 정확히 읽을 수 있으면장애의 원인이 클라이언트인지, 애플리케이션인지,프록시인지, 인프라인지를 30초 안에 판단할 수 있습니다.

외우지 마세요.이 글을 북마크하고 장애가 터졌을 때 꺼내 보세요.

본 글은 리원에이스 기술개발본부가 작성한 기술 콘텐츠입니다. 외부 공유 시 출처를 명시해 주세요.

2026년 8월 19일
리원에이스 기술개발본부