
열리는 것과 맞는 것은 다른 이야기였다.
배포 점검 목록에 이런 줄이 있다. robots.txt 200, sitemap 200, ads.txt 200. 초록불이 뜨면 넘어간다. 나도 그렇게 했고, 2주 뒤에 사이트맵이 전체의 5분의 1만 담고 있는 걸 발견했다. 상태코드는 내내 200이었다.
200이 통과 신호가 되어 버리는 이유
세 가지 구조가 겹친다.
첫째, 정적 파일은 이름만 맞으면 응답한다. 웹 최상위에 누가 언제 만들었는지 모를 Sitemap.xml이 놓여 있어도 서버는 그걸 성실하게 내준다. 내용이 낡았는지는 서버가 알 바가 아니다.
둘째, CMS가 없는 주소를 삼킨다. 워드프레스는 못 찾은 주소를 다양한 방식으로 처리하는데, 그 과정에서 404 대신 200이 나오는 경로가 생긴다. 대소문자만 다른 주소가 살아 있는 것처럼 보이는 일도 여기서 온다.
셋째, CDN과 캐시가 옛 응답을 붙잡고 있다. 원본에서 지운 파일이 한동안 200으로 계속 나온다.
세 경우 모두 curl -o /dev/null -w '%{http_code}'는 200을 준다. 이 명령은 파일이 존재하는지를 묻는 명령이지 맞는 파일인지를 묻는 명령이 아니다. 물어본 적 없는 것에 답을 얻었다고 여긴 게 실수였다.
그래서 무엇을 세는가
파일마다 세어야 할 것이 다르다. 상태코드 대신 이 숫자를 본다.
파일세는 것맞는지 보는 기준
| sitemap | <loc> 개수 | 실제 글 수와 일치 |
| sitemap index | 최상위 태그 | sitemapindex여야 한다. urlset이면 색인이 아니라 낱장이다 |
| robots.txt | Disallow 줄 · Sitemap 줄 | 차단이 의도한 경로뿐인가, 사이트맵 주소가 살아 있는가 |
| ads.txt | 게시자 ID | 광고 콘솔의 ID와 문자 단위로 일치 |
| 소유확인 파일 | 존재 여부 | 정리하다 지우지 않았는가 |
내 경우 최상위 태그 한 글자에 답이 있었다. robots.txt가 가리키던 파일은 urlset으로 시작했고, 진짜 색인은 sitemapindex로 시작했다. 열어서 첫 줄만 봤어도 잡혔을 일이다.
한 줄로 확인하기
robots.txt에 적힌 사이트맵 주소를 그대로 따라가서 주소 개수를 세는 것까지 한 번에 한다.
curl -s https://example.com/robots.txt | grep -i '^sitemap:' | awk '{print $2}' \
| xargs -I{} sh -c 'echo -n "{} -> "; curl -s "{}" | grep -c ""'
사이트맵 색인을 쓰고 있으면 이 숫자는 하위 사이트맵 개수로 나온다. 그때는 나온 주소를 한 번 더 따라가 글 사이트맵에서 세면 된다. 어느 쪽이든 마지막에 남는 건 숫자 하나이고, 그 숫자를 내가 아는 글 수와 대면 끝이다.
점검표에 적을 문장도 바뀐다. 사이트맵 200이 아니라 사이트맵 주소 개수 = 글 수로 적는다. 앞 문장은 서버에게 묻는 것이고 뒤 문장은 나에게 묻는 것이다.
남는 이야기
이 습관은 사이트맵에만 걸리는 게 아니다. 헬스체크 엔드포인트가 200을 주지만 뒤쪽 DB 연결은 끊겨 있는 경우, 설정 파일을 읽는 데는 성공했는데 값이 기본값인 경우가 같은 모양이다. 응답이 왔다는 사실과 응답이 맞다는 사실 사이에는 확인 한 단계가 더 있다.
싱겁지만 비용이 싸다. 세는 데 10초 걸린다.

'think' 카테고리의 다른 글
| 정년퇴직 재고용, 근속 30년이 0이 될 수 있습니다 (0) | 2026.08.06 |
|---|---|
| 정년퇴직 실업급여, 이직확인서에 뭐라 적혔는지부터 봅니다 (0) | 2026.08.06 |
| CLAUDE.md 파일 위치 4곳, 로드 순서가 결과를 가릅니다 (0) | 2026.08.05 |
| NIST 클라우드 정의 필수 특성 5가지, 첫 줄이 판별 기준입니다 (0) | 2026.08.05 |
| 예금토큰 뜻, 프로젝트 한강과 결제 인프라 사업은 다릅니다 (0) | 2026.08.05 |
댓글