운영 중 가장 자주 만나는 오류는 네 가지입니다. 403(권한), 504(지연/타임아웃), CORS(브라우저 차단), 리다이렉트 루프(무한 이동)입니다. 본 글은 “그럴듯한 추측”이 아니라, 어디를 보면 바로 결론이 나는지에 집중해서 정리합니다.
공통 1분 점검
①
② 웹서버/프록시 로그를 봅니다(타임아웃은 “어느 단계에서” 끊겼는지 중요합니다)
③ 브라우저 개발자도구(Network/Console)로 CORS/리다이렉트 원인을 확정합니다
①
curl -I로 상태코드/Location/서버를 확인합니다② 웹서버/프록시 로그를 봅니다(타임아웃은 “어느 단계에서” 끊겼는지 중요합니다)
③ 브라우저 개발자도구(Network/Console)로 CORS/리다이렉트 원인을 확정합니다
0) 공통 진단 명령(이거부터 합니다)
# 헤더만 확인(리다이렉트/서버 확인)
curl -I https://example.com/path
# 리다이렉트를 따라가며 확인(무한 루프/Location 확인)
curl -IL https://example.com/path
# 타임아웃을 짧게 주고 어디서 지연되는지 확인
curl -m 10 -v https://example.com/path
1) 403 Forbidden: “권한/차단/인증 실패”입니다
가장 흔한 원인 TOP 6
- 정적 파일 권한 문제(소유자/권한/SELinux 등)
- 웹서버 설정에서 deny 또는 접근 제한이 걸림
- 인증/인가(로그인) 실패인데 403으로 내려주는 케이스
- WAF/보안장비가 특정 패턴을 차단
- 디렉터리 인덱싱/접근 설정(예: Apache Options, Require)
- 리버스 프록시 뒤에서 IP 허용 목록이 맞지 않음
로그에서 바로 확인하는 위치
- Nginx:
error.log(permission denied, access forbidden) - Apache:
error_log(client denied by server configuration) - 애플리케이션(예: Spring): 인증/권한 예외(AccessDenied) 확인
Nginx 접근 제한 예시(참고)
location /admin {
allow 1.2.3.4;
deny all;
}
2) 504 Gateway Timeout: “뒤쪽(업스트림)이 늦거나 죽었습니다”
원인 TOP 6
- 앱 서버(Tomcat/Node 등)에서 요청 처리 시간이 너무 김(DB 지연 포함)
- 프록시(Nginx/ALB/Cloudflare 등) 타임아웃 설정이 짧음
- 업스트림 연결이 끊김(재시도/커넥션 리셋)
- DB 락/슬로우쿼리로 인해 응답 지연
- 메모리 부족/GC/스레드 고갈로 처리 불가
- 대용량 업로드/다운로드에서 버퍼/타임아웃 충돌
어디서 끊겼는지 “단계”를 확인합니다
- 웹서버가 504를 냈는지, 로드밸런서가 냈는지(응답 헤더/서버 표기) 확인합니다.
- 앱 로그에 해당 요청의 시작/끝 로그가 남는지 확인합니다(끝이 없다면 처리 중 정지 가능성이 큽니다).
- DB slow query 로그/모니터링에서 동일 시간대 스파이크가 있는지 확인합니다.
Nginx 타임아웃 기본 점검(참고)
proxy_connect_timeout 5s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
send_timeout 60s;
※ 타임아웃을 무작정 늘리기 전에 “왜 느린지(DB/스레드/GC)”를 먼저 잡는 것이 정석입니다.
3) CORS 오류: 서버가 아니라 “브라우저가 막습니다”
증상
- 브라우저 Console에 CORS policy 오류가 뜹니다.
- 서버는 200을 찍는데, 브라우저에서만 호출이 실패합니다.
핵심 원리(필수 3줄)
- 브라우저는 출처(origin)가 다르면 차단할 수 있습니다.
- 서버가
Access-Control-Allow-Origin등 헤더로 허용해야 합니다. - PUT/DELETE/커스텀헤더/JSON 등은 preflight(OPTIONS)가 먼저 날아갑니다.
서버가 내려야 할 대표 헤더
Access-Control-Allow-Origin: https://frontend.example.com
Access-Control-Allow-Methods: GET,POST,PUT,DELETE,OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Allow-Credentials: true
※ Allow-Origin: * 과 Allow-Credentials: true 는 함께 쓸 수 없습니다.
4) 리다이렉트 무한 루프(ERR_TOO_MANY_REDIRECTS): “중복 리다이렉트”입니다
가장 흔한 패턴
- 웹서버에서 HTTP→HTTPS 리다이렉트 + 앱(워드프레스/스프링)에서도 HTTPS 강제
- 프록시 뒤에서 앱이 “내가 HTTP로 접속했다”고 착각(Forwarded/Proto 헤더 누락)
- www ↔ non-www 리다이렉트가 양쪽에서 동시에 걸림
- Cloudflare/로드밸런서 SSL 모드와 원본 서버 설정이 충돌
확인 방법(이걸로 끝납니다)
curl -IL로 Location이 어디로 반복되는지 확인합니다.- 리다이렉트 규칙을 한 곳(웹서버 또는 앱)에만 남기고 나머지는 제거합니다.
- 프록시 환경이면 X-Forwarded-Proto 또는 Forwarded 헤더 설정을 확인합니다.
Nginx HTTPS 리다이렉트 예시(참고)
server {
listen 80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
공식 참고 링크