먼저 edge와 원본을 같은 요청으로 나눕니다
Cloudflare 뒤의 사이트가 느리거나 520, 521, 522, 524, 525, 526을 반환할 때 DNS, WAF, 캐시, Tunnel, 원본 웹 서버를 한꺼번에 바꾸면 최초 실패 지점을 잃기 쉽습니다. 먼저 사용자가 받은 edge 응답과 원본이 실제로 낸 응답을 같은 URL, 시각, Host 조건으로 비교해야 합니다.
조사 메모에는 전체 URL, 발생 시각과 시간대, HTTP 상태, Cf-Ray를 한 묶음으로 남깁니다. Cf-Ray는 요청을 Cloudflare 로그와 원본 로그에서 연결하는 식별자이지 오류 원인을 단독으로 설명하는 값은 아닙니다. 캐시 상태 역시 HIT, MISS, DYNAMIC 중 하나라는 이유만으로 정상이나 장애를 확정할 수 없습니다.
실제 504 조사: 알림 시각과 장애 시각이 달랐던 사례
2026-10-22 이 사이트의 Search Console 서버 오류 알림을 조사했습니다. 현재 경로는 Cloudflare Tunnel → Nginx → PHP-FPM → WordPress/MariaDB입니다. 원본 로그와 Google의 저장된 검사 결과, 현재 요청을 시간순으로 대조하니 서로 다른 사실을 분리할 수 있었습니다. 아래 시각은 UTC이며 한국시간은 9시간을 더합니다.
# Observed origin records; IPs and other identifiers omitted
2026-10-16T17:17:40Z GET /privacy-policy/ status=504
upstream timed out ... while reading response header from upstream
| UTC 시각 | 확보한 관찰 | 해석의 한계 |
|---|---|---|
| 10월 16일 17:17:40 | /privacy-policy/ 원본 access 로그 504, error 로그의 upstream 응답 헤더 timeout | Nginx가 FastCGI 응답 헤더를 기다리다 실패한 기록. 어느 PHP 함수·DB 요청이 느렸는지는 확정 불가 |
| 10월 20일 01:36:41 | 같은 URL의 Google 저장 검사: fetch 성공·색인됨 | 첫 오류 뒤 성공한 재크롤 기록. 현재 실시간 검사를 뜻하지 않음 |
| 10월 22일 07:56:26 | Search Console 서버 오류 알림 수신 | 메일 도착 시각을 장애 발생 시각으로 쓰면 로그 검색 범위를 놓침 |
| 10월 22일 조사 시점 | 현재 sitemap의 고유 URL 130개 모두 HTTP 200 | 현재 접근 가능성만 확인. 과거 실패가 없었다는 증거는 아님 |
보존된 9월 12일~10월 22일 원본 요청 102,944건 중 원본 5xx는 위 한 건이었습니다. 하지만 전체 글의 Google 저장 검사에는 다른 URL 3개의 5xx도 남아 있었고, 이 URL들은 현재 요청에서 모두 200이었습니다. 원본에 대응되는 오류가 없다는 이유로 Cloudflare 장애라고 확정하지 않았습니다. 당시 edge 응답과 Ray ID가 없어 이 세 건의 발생 계층은 미확인으로 남겼습니다.
원본 로그의 User-Agent는 Googlebot이었지만 Tunnel 뒤 원본 접속 주소만으로 실제 Googlebot IP를 확인할 수 없었습니다. User-Agent 재현 요청도 Google의 실제 요청을 대신하지 못합니다. URL Inspection API는 Google에 저장된 상태를 반환하므로, ‘현재 curl 200’과 ‘과거 Google 5xx’가 동시에 보일 수 있습니다.
이번 사례로 확인한 범위: 과거 FastCGI timeout 한 건, 이후 성공한 저장 크롤, 현재 접근 정상입니다. 특정 플러그인·메모리 부족·PHP 취약점이 원인이었다거나 이번 서비스 재시작으로 그 장애를 고쳤다고 주장할 근거는 없습니다. 같은 문제가 다시 생기면 요청 시각·Ray ID·원본 처리 시간과 PHP slow log를 같은 시간대로 수집해야 다음 원인을 좁힐 수 있습니다.
Nole IT 운영 환경에서 확보한 정상 기준선
아래 결과는 2026-08-08에 이 사이트의 Synology NAS, Docker WordPress, MariaDB, Cloudflare Tunnel/DNS 경로에서 직접 확인한 기준선입니다. 공개 식별값은 제거했으며 장애를 일부러 발생시킨 재현 결과는 아닙니다. 정상일 때 어느 계층까지 응답하는지 보존해 두면 이후 장애 결과와 비교할 수 있습니다.
# 2026-08-08, identifying values redacted
EDGE HTTP 200 | server=cloudflare | cf-cache-status=DYNAMIC | cf-ray=present
ORIGIN HTTP 200 | server=Apache/2.4.x (Debian)
DNS two proxied A answers
TLS wildcard SAN matched | certificate valid at test time
이 기준선에서 edge와 원본이 모두 HTTP 200이므로 당시 Cloudflare에서 원본까지의 전달 경로는 정상입니다. cf-cache-status=DYNAMIC은 이 WordPress 응답이 일반 캐시 적중이 아니라는 뜻일 뿐 지연의 증거가 아닙니다. 다음 장애 때 동일 명령으로 원본만 빠른지, 두 경로가 모두 느린지 비교해야 의미가 생깁니다.
Oracle 이전 뒤의 별도 정상 관찰
2026-09-13 UTC 11:21에 현재 Oracle 운영 경로를 읽기 전용으로 확인했습니다. 공개 HTTPS 홈과 관리 접속을 통한 같은 Host의 원본 HTTP 홈이 각각 200을 반환했습니다. 두 요청은 별도 시점에 실행했으며 부하·응답 시간 비교나 5xx 복구 실험은 아닙니다. 위 2026-08-08 NAS 결과는 과거 관찰로 보존합니다.
Oracle 이전 후 본문·URL·이미지·DB 검증 기록
변경 전에 한 번에 저장할 값
| 계층 | 저장할 값 | 판단 기준 |
|---|---|---|
| 클라이언트와 edge | URL, 시각, 상태, Cf-Ray, cf-error-type |
Cf-Ray가 있으면 Cloudflare를 경유한 응답으로 추적 |
| 캐시 | cf-cache-status, 응답 시간, 재시도 결과 |
캐시 상태와 원본 접촉 여부를 함께 해석 |
| 원본 | 같은 Host의 직접 응답, 웹 서버 로그, 애플리케이션 로그 | edge와 원본의 상태·시간 차이로 실패 구간 분리 |
| TLS | SNI, 인증서 SAN, 만료, 원본 TLS 로그 | 525와 526은 재시도보다 인증서 경로 수정이 우선 |
| 보안 규칙 | Security Events의 action, rule ID, 요청 시각 | 이벤트가 있을 때만 WAF 예외를 최소 범위로 검토 |
curl -sS -D edge.headers -o /dev/null https://example.com/
curl -sS -D origin.headers -o /dev/null -H 'Host: example.com' http://<ORIGIN_IP>:<PORT>/
grep -Ei '^(HTTP/|server:|cf-ray:|cf-cache-status:|cf-error-type:|cf-error-origin:)' edge.headers
원본 직접 요청은 관리 네트워크나 인증된 진단 경로에서만 수행합니다. 진단을 위해 공개 DNS의 프록시를 끄거나 원본 주소를 인터넷에 노출하지 않습니다. Tunnel을 쓰면 외부에서 원본 IP로 우회할 수 없을 수 있으므로, 원본 LAN 또는 같은 Docker host에서 동일 Host 헤더로 확인합니다.
5xx 코드가 가리키는 첫 점검 지점
| 상태 | Cloudflare가 구분하는 범위 | 먼저 볼 곳 |
|---|---|---|
520 |
원본의 비어 있거나 알 수 없거나 비정상적인 응답 | PHP/웹 서버 crash, 과도한 헤더, 조기 연결 종료 |
521 |
원본 웹 서버가 연결을 거부하거나 내려간 상태 | listen port, 서비스 상태, Cloudflare 주소 차단 |
522 |
Cloudflare와 원본 사이 TCP 연결 시간 초과 | 방화벽, 라우팅, 원본 부하, 연결 수 |
524 |
원본 연결 뒤 응답 대기 시간 초과 | 느린 요청, DB 잠금, upstream 처리 시간 |
525 |
Cloudflare와 원본 사이 TLS handshake 실패 | SNI, cipher, 원본 인증서와 TLS 오류 로그 |
526 |
원본 인증서 검증 실패 | 인증서 체인, 이름 일치, 만료, SSL 모드 |
500, 502, 503, 504는 Cloudflare가 만든 응답인지 원본 응답을 전달한 것인지 화면만으로 단정하지 않습니다. 응답의 cf-error-type, 원본 로그, Error Analytics의 edge/origin 상태를 함께 봅니다. Cloudflare가 만든 최신 오류 응답은 Accept: application/json 요청에서 구조화된 정보를 줄 수 있지만, 원본이 만든 5xx 본문까지 바뀌는 것은 아닙니다.
curl -sS --compressed -H 'Accept: application/json' https://example.com/cdn-cgi/error/522
curl -sS --compressed -D - -o /dev/null -H 'Accept: application/json' https://example.com/cdn-cgi/error/521
이 경로는 오류 응답 형식을 보는 데모입니다. /cdn-cgi/error/522에서 522가 나와도 내 원본 서버가 timeout 났다는 증거가 아닙니다. 실제 장애 판정은 사용자가 실패한 원래 URL로 해야 합니다. 데모 응답, 정상 기준선, 실제 장애 로그를 서로 다른 기록으로 보관하세요.
HTTP 원본 비교는 Tunnel이 해당 HTTP 서비스로 연결되는 구성에 해당합니다. 원본 자체가 HTTPS라면 HTTP로 낮춰 비교하지 말고 원래 hostname과 SNI를 유지하는 HTTPS 요청으로 확인해야 합니다. edge 인증서가 정상이라는 사실도 원본 인증서 검증까지 통과했다는 뜻은 아닙니다.
로그를 시간순으로 맞추는 순서
- 실패 요청 한 건을 다시 만들고 URL, UTC 또는 명시한 지역 시간, 상태,
Cf-Ray를 기록합니다. 여러 번 새로 고친 결과를 섞지 않습니다. - Cloudflare Security Events에서 같은 시각의 차단 action이 있는지 확인합니다. 이벤트가 없는데 WAF를 끄는 조치는 중단합니다.
- 사용 가능한 요금제와 로그 기능에서
Cf-Ray또는 Ray ID로 검색하고 edge status와 origin status를 비교합니다. 로그 접근 범위는 요금제에 따라 다를 수 있습니다. - 원본 웹 서버 access/error 로그에서 같은 시각과
Cf-Ray를 찾습니다. 원본 로그에 요청이 없다면 애플리케이션 수정 전에 Tunnel, 방화벽, TLS 연결을 봅니다. - 원본 로그에 정상
HTTP 200이 있는데 edge만 오류라면 응답 헤더 크기, 조기 연결 종료, Transform/Worker 규칙을 좁힙니다. 원본도 5xx라면 애플리케이션과 DB 로그가 우선입니다.
Logpush의 OriginResponseStatus가 0이라고 해서 항상 원본 장애는 아닙니다. 같은 레코드의 CacheStatus가 hit 또는 revalidated면 원본에 접촉하지 않은 정상 캐시 경로일 수 있습니다. 반대로 miss 또는 expired인데 OriginResponseStatus가 0이면 원본이 HTTP 헤더를 보내기 전에 연결이 끊긴 경로를 의심할 근거가 됩니다.
수정은 한 계층씩 적용합니다
- Security Events에 특정 rule ID가 실제로 찍혔을 때만 해당 path, method, source 조건으로 Skip 범위를 좁힙니다. WAF 전체 비활성화는 비교 실험으로도 피합니다.
521또는522면 원본 서비스의 listen 상태와 Cloudflare/Tunnel 연결을 먼저 복구합니다. 캐시 purge는 TCP 연결 실패를 고치지 못합니다.524면 timeout 값을 바로 키우기 전에 원본 처리 시간, DB 잠금, 외부 API 대기를 측정합니다. 느린 경로를 숨기는 설정 변경은 되돌리기 어렵습니다.525또는526이면 Flexible로 낮춰 고정하지 않습니다. 원본 인증서, SNI, 체인과 Cloudflare SSL 모드가 일치하도록 수정합니다.- 특정 path만 실패하면 Worker, Redirect Rule, Transform Rule을 하나씩 비활성화한 비교 요청으로 범위를 줄이고 원래 값과 우선순위를 기록합니다.
검증과 롤백
수정 후에는 처음 기록한 URL과 요청 조건으로 edge 요청과 원본 요청을 다시 수행합니다. 상태만 HTTP 200으로 바뀌었는지 보지 말고 응답 시간, Cf-Ray 추적 가능 여부, 원본 로그 도착 여부도 함께 확인합니다. 정상 요청 하나와 실패하던 요청 하나를 각각 남기면 캐시성 성공을 줄일 수 있습니다.
규칙 변경 전 expression, action, 우선순위를 저장하고, 원본 설정은 파일 백업이나 배포 revision으로 되돌릴 수 있어야 합니다. 문제가 다른 계층으로 이동하거나 정상 트래픽이 차단되면 마지막 한 변경만 되돌린 뒤 기준선과 다시 비교합니다.
같이 확인할 글
공식 문서 및 확인 기준
- Cloudflare 5xx errors – 오류 코드별 edge와 원본 조사 범위
- Gathering information for troubleshooting sites – 직접 원본 비교와 Cf-Ray 로그 연결
- Cloudflare error diagnostic headers – cf-error-type과 cf-error-origin 해석
- Cloudflare Error 520 – CacheStatus와 OriginResponseStatus를 함께 보는 기준