잘못된 글 주소를 열었는데 홈 화면이 나온다. CSS 요청은 200인데 화면은 깨진다. 상태 코드만 확인하면 둘 다 성공처럼 보이지만, 요청한 콘텐츠를 받은 것은 아니다. 정적 블로그에서 마지막 fallback이 무엇을 반환하는지 확인하는 방법을 살펴본다.

같은 파일에 두 가지 마지막 처리 방식을 적용했다

없는 파일과 홈 화면을 구분: 없는 글, 없는 스타일, 실제 응답
AI 생성 개념도 · 없는 글·스타일 파일이 홈 HTML로 돌아오는 경우와 실제 리소스 부재 응답을 구분했습니다. 정적 사이트와 SPA의 처리 조건은 본문에서 나눕니다. 본문 근거와 적용 조건 · 그림을 누르면 원본 크기로 볼 수 있습니다.

최초 실험에서는 home-v1이라는 본문을 가진 index.html을 만들고, 없는 경로를 404로 끝내는 설정과 홈 파일로 넘기는 설정을 비교했다. 아래 코드는 server 블록 안의 경로 처리 부분이며 완전한 Nginx 설정은 아니다.

로컬 실험의 location 설정 일부
location / {
    try_files $uri $uri/ =404;
}
location /fallback/ {
    try_files $uri /index.html;
}
직접 관찰한 결과 · 2026-09-12
설정HTTP 상태확인한 본문
파일 없으면 종료404기본 오류 응답
홈으로 넘김200home-v1 (홈 파일)

try_files는 지정한 후보를 확인하고 마지막 인자로 다음 처리 방식을 정한다. 이 실험의 /fallback/에서 파일을 찾지 못하면 /index.html로 내부 이동해 홈 본문을 받았다. 브라우저 주소가 홈 주소로 바뀌는 301 리디렉션과는 다르다.

없는 CSS도 홈 HTML로 돌아왔다

9월 22일 KST 보강 실험에서는 article.html을 추가하고 글과 자산 경로를 나눠 요청했다. 정상 글은 article-v1을 반환했다. 엄격한 경로의 없는 글과 CSS는 404였고, fallback 경로의 두 요청은 모두 200과 home-v1이었다.

직접 관찰한 결과 · 2026-09-21
요청 경로HTTP 상태홈 본문과 일치
/article.html200아님
/missing-post/404아님
/assets/missing.css404아님
/fallback/missing-post/200일치
/fallback/assets/missing.css200일치

CSS라는 확장자의 URL을 요청했다는 사실이 응답도 CSS임을 보장하지 않았다. 이 결과에서는 브라우저 렌더링 오류를 측정하지 않았지만, 자산 요청에 홈 본문이 돌아오는 잘못된 전달은 HTTP 응답만으로 확인할 수 있었다.

내 사이트에서는 세 주소의 헤더와 본문을 보관한다

내 사이트에서는 세 주소의 헤더와 본문을 보관한다의 판단 조건을 설명하는 개념 그림
AI 생성 개념도 · 내 사이트에서는 세 주소의 헤더와 본문을 보관한다에 관한 설명용 그림입니다. 구체적인 조건·계산·확인 범위는 아래 본문을 따르며, 실제 화면이나 관찰·측정 자료가 아닙니다. 본문 근거와 적용 조건 · 그림을 누르면 원본 크기로 볼 수 있습니다.
기존 파일을 덮어쓰지 않는 별도 작업 폴더에서 실행
# example.com과 경로를 자신의 사이트·실제 글로 바꾼다.
curl -sS --connect-timeout 3 --max-time 10 \
  -D known.headers -o known.html https://example.com/notes/existing/
curl -sS --connect-timeout 3 --max-time 10 \
  -D missing.headers -o missing.html https://example.com/check-missing-article/
curl -sS --connect-timeout 3 --max-time 10 \
  -D asset.headers -o asset.body https://example.com/assets/check-missing.css
대상기대하는 확인예상과 다르면
실제로 존재하는 글200과 해당 글 제목·내용대표 도메인·웹 루트·배포 파일을 확인한다
일부러 만든 없는 글404와 오류 안내try_files의 마지막 경로와 오류 페이지의 상태 처리를 확인한다
일부러 만든 없는 CSS404이며 성공한 홈 응답이 아님자산 전용 location 또는 공통 fallback이 적용되는지 확인한다

이 명령은 본문을 버리지 않고 파일로 저장한다. -L을 사용하지 않아 이동 응답이 있으면 첫 상태와 Location을 먼저 읽을 수 있다. 404를 정상적인 진단 결과로 보므로 --fail도 넣지 않았다. curl의 종료 코드 0과 HTTP 200은 같은 의미가 아니다. 요청이 끝나면 헤더 첫 줄과 저장한 본문을 함께 확인한다.

정적 사이트와 SPA는 마지막 처리를 다르게 판단한다

URL마다 HTML 파일이 있는 정적 사이트는 파일이 없을 때 실제 404로 끝내는 구성이 맞을 수 있다. 반면 브라우저 라우터가 화면 경로를 해석하는 SPA는 유효한 앱 경로에 공통 HTML을 제공해야 할 수 있다. SPA의 공통 HTML 반환 자체를 오류로 단정하지 말고, 누가 경로를 해석하는지와 앱이 없는 경로를 어떻게 처리하는지를 구분한다.

API와 CSS·이미지 같은 자산은 앱 화면의 경로와 같은 규칙으로 처리해도 되는지 따로 판단한다. 이 글은 실제 SPA를 실행한 실험이 아니므로 특정 프레임워크의 최종 오류 처리나 검색 수집 결과까지 보장하지 않는다.

수정 후 정상 글·없는 글·자산을 다시 검사한다

수정 후 통과 조건을 주소별로 적어 둡니다. 정상 글은 200과 기대한 글 본문, 없는 글은 404와 오류 문서, 정상 CSS는 200과 CSS 본문이어야 합니다. 없는 CSS는 홈 문서와 200으로 바꾸지 않습니다. 친절한 HTML 오류 화면을 쓰더라도 상태가 404이면 ‘오류 화면이 예쁘다’와 ‘존재하는 자원이다’를 혼동하지 않을 수 있습니다. 상태·Content-Type·본문 중 하나만 검사하면 이번 fallback 실험의 잘못된 응답을 놓칠 수 있습니다.

편집자 의견

정적 글 사이트에서는 없는 문서를 홈으로 돌려주는 친절함보다 요청한 자원이 없다는 사실을 정확히 알리는 편이 낫다고 판단합니다. 실험에서 없는 CSS까지 200 HTML이 되어 상태 코드만 보는 확인을 통과했기 때문입니다.

클라이언트 라우팅이 필요한 SPA라면 문서 경로의 대체 처리는 검토할 수 있습니다. 그때도 자산 요청과 실제 없는 콘텐츠까지 같은 홈 응답으로 묶을지는 별도로 결정하겠습니다.

판단 근거: 없는 CSS도 홈 HTML로 돌아왔다

의견 추가 2026-10-23 · 본문 자료를 바탕으로 한 편집 판단

실험 환경과 원자료

nginx version: nginx/1.18.0 (Ubuntu) · Linux · Python 3.10.12
로컬 임시 디렉터리 · 단일 실행 · 실제 운영 트래픽 제외

관찰 시각: 2026-09-12T13:53:51.407530+00:00

Python 3과 Nginx가 있는 별도 실험 환경에서 실행합니다. 스크립트는 임시 폴더와 로컬 포트를 만들며, 종료할 때 자신이 시작한 프로세스만 정리합니다.

python3 run-lab.py --output observations.json

참고한 공식 문서

기존 자료 확인: 2026-09-22 · 원고 수정: 2026-10-24. 잘못된 내용은 정정 요청으로 알려주세요.

추가 실험의 환경과 원자료

관찰 시각: 2026-09-21T16:17:49.564298+00:00
os: Linux · python: 3.10.12 · nginx: nginx version: nginx/1.18.0 (Ubuntu)

고유 임시 경로·루프백 포트의 Nginx. 후보 검사와 교체, 해당 master에만 HUP, 순차 GET 요청. 운영 설정·서비스·외부 API를 사용하지 않았다.

확인하지 않은 범위: 단일 실행. 무중단성·동시 접속·잘못된 설정의 실제 reload·CDN·브라우저 라우터·검색엔진의 soft 404 판정은 시험하지 않았다.

Python 3과 Nginx가 설치된 별도 Linux 환경에서 실행합니다. 관리자 권한은 필요하지 않습니다. 임시 파일과 스크립트가 만든 자식 프로세스만 사용하며, 기존 결과 파일은 덮어쓰지 않습니다.

python3 lab-nginx-candidate-routes.py --output new-observations.json

이 글의 보완 기록

  • · 없는 CSS까지 비교한 새 실험과 세 URL 진단 명령, 정적 사이트/SPA의 적용 범위를 보강했다.
  • · 본문 근거에 대한 편집자의 판단과 결론이 달라지는 조건을 추가했습니다. 기존 관찰일·공식 자료 확인일은 유지했습니다.
  • · 글별 적용 사례와 반례를 보강했습니다. 기존 관찰일과 원자료 확인일은 유지했습니다.