이 메시지가 뜻하는 것
서치 콘솔의 URL 검사에서 이런 문구를 봤을 겁니다(한국어 화면에서는 같은 뜻의 번역문으로 나옵니다).
Indexing allowed? No: ‘noindex’ detected in ‘X-Robots-Tag’ http header
페이지 색인 생성 보고서에서는 그 URL이 “‘noindex’ 태그에 의해 제외됨”(Excluded by ‘noindex’ tag)에 들어가 있습니다. 구글이 페이지를 가져갔고, HTTP 응답에 이런 헤더가 붙어 있었다는 뜻입니다.
X-Robots-Tag: noindex
구글은 이것을 HTML 안의 <meta name="robots" content="noindex">와 똑같이 취급해서, 그 페이지를 검색 결과에 보여 주지 않습니다. 차이는 눈에 보이지 않는다는 점입니다. 헤더는 HTML보다 앞서 응답과 함께 오고, 페이지 소스 보기에는 나오지 않습니다. 멀쩡해 보이는 페이지를 한참 들여다봐도 원인을 못 찾는 이유입니다.
X-Robots-Tag와 메타 robots의 차이
둘 다 같은 지시어(noindex, nofollow, none, nosnippet, unavailable_after 등)를 씁니다. 헤더에만 있는 특징이 몇 가지 있습니다.
- 어떤 파일 형식에도 쓸 수 있습니다. PDF, 이미지 같은 HTML이 아닌 파일은
<head>가 없으므로 헤더로만 색인에서 뺄 수 있습니다. - 특정 크롤러만 지정할 수 있습니다.
X-Robots-Tag: googlebot: noindex는 구글에만 적용됩니다. 크롤러 이름이 없으면 모두에게 적용됩니다. - 여러 개가 합쳐집니다. 응답 하나에
X-Robots-Tag헤더가 여러 개 있을 수 있고, HTML의 메타 robots 태그와 함께 모두 읽힙니다. - 가장 제한적인 지시가 이깁니다. 한 계층은
noindex, 다른 계층은index, follow라고 하면 페이지는 색인되지 않습니다.index는 원래 기본값이라 아무것도 취소하지 못합니다.none은noindex, nofollow와 같습니다.
그래서 해결책은 결코 “어딘가에 index 헤더를 추가”가 아닙니다. noindex를 붙이는 곳을 찾아 멈추는 것입니다.
1단계: 헤더를 직접 확인하기
curl -sI https://example.com/page | grep -i '^x-robots-tag'
-I는 HEAD 요청입니다. HEAD와 GET에 다르게 응답하는 애플리케이션도 있으므로, 아무것도 안 나오면 실제 GET을 보내고 헤더만 출력해 보세요.
curl -s -o /dev/null -D - https://example.com/page
그다음 Googlebot으로 같은 요청을 합니다. 봇 관리, WAF 규칙, A/B 테스트 도구, 일부 플러그인은 크롤러를 다르게 대하므로 noindex가 크롤러에게만 붙을 수 있습니다.
curl -s -o /dev/null -D - \
-A "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)" \
https://example.com/page
URL이 리다이렉트된다면 -L을 붙이고 헤더 묶음을 하나씩 모두 읽으세요. 색인에 중요한 것은 최종 URL, 즉 구글이 색인하길 바라는 그 URL입니다.
HTTP 점검은 리다이렉트를 따라간 최종 응답의 X-Robots-Tag 값을 내 네트워크 밖에서 보여 줍니다. 자체 User-Agent를 쓰므로, Googlebot에게만 걸리는 규칙은 위의 curl 명령으로 확인해야 합니다.
이렇게 해도 noindex가 안 보이는데 서치 콘솔에는 계속 뜬다면, 대부분 둘 중 하나입니다.
- 검사 결과가 예전 크롤링 기준입니다. URL 검사의 기본 화면은 구글이 마지막으로 크롤링했을 때 본 내용입니다. “실제 URL 테스트”(Test live URL)를 눌러 지금 가져오게 하세요.
- 구글이 받는 응답이 내가 받는 응답과 다릅니다. 구글 IP 대역이나 검증된 봇 여부로 동작하는 규칙은 User-Agent를 맞춰도 내 노트북의 curl에는 걸리지 않습니다. 구글 쪽에서 본 모습은 실제 URL 테스트가 유일합니다. “테스트된 페이지 보기”(View tested page)의 “추가 정보”(More info) 탭에 구글이 받은 HTTP 응답 헤더가 나옵니다.
2단계: 어느 계층에서 붙는지 찾기
응답은 여러 계층을 거치고, 그중 어디서든 헤더를 붙일 수 있습니다. 바깥에서 안쪽으로 좁혀 가세요.
CDN 건너뛰기
--resolve로 DNS를 우회해서, 올바른 호스트명으로 원 서버에 직접 물어봅니다.
curl -s -o /dev/null -D - --resolve example.com:443:203.0.113.10 https://example.com/page
원 서버 응답에는 X-Robots-Tag가 없는데 공개 응답에는 있다면 CDN이나 엣지가 붙이는 것입니다. 원 서버에도 이미 있다면 더 안쪽으로 들어갑니다.
CDN·엣지 규칙
- Cloudflare: 응답 헤더를 수정하는 Transform Rules, 그 경로에 걸린 Worker, Cloudflare Pages라면
_headers파일. - Netlify:
_headers파일과netlify.toml의[[headers]]섹션. - Vercel:
vercel.json의headers, Next.js라면next.config.js의headers(). - 그 밖에 헤더 규칙이나 엣지 함수가 있는 CDN이라면 설정에서
robots를 검색하세요.
CDN에는 함정이 하나 더 있습니다. 캐시된 응답은 헤더도 함께 보관합니다. 원 서버가 한때 noindex를 보냈고 CDN이 그 응답을 캐시했다면 원 서버를 고쳐도 소용없습니다. 해당 URL의 캐시를 비우세요.
호스팅의 프리뷰 배포
호스팅 플랫폼은 시험용 배포가 구글에 들어가지 않도록 프리뷰 빌드에 일부러 X-Robots-Tag: noindex를 붙입니다. Vercel은 Preview Deployment에, Netlify는 Deploy Preview에, Cloudflare Pages는 pages.dev의 프리뷰 배포에 붙입니다.
이것은 올바른 동작입니다. 문제는 공개 호스트명이 실제로는 프리뷰를 내보내고 있을 때 생깁니다. 사용자 도메인이 엉뚱한 브랜치나 배포에 연결돼 있거나, 사이트가 주로 프리뷰 URL로 노출되고 있는 경우입니다. 플랫폼의 도메인 설정에서 도메인이 어느 배포를 가리키는지 확인하세요.
웹 서버 설정
nginx:
add_header X-Robots-Tag "noindex, nofollow" always;
include까지 포함해 실제로 적용 중인 전체 설정에서 찾습니다.
sudo nginx -T 2>/dev/null | grep -n -i 'x-robots-tag'
nginx의 상속 규칙에 주의하세요. location 블록은 자기 안에 add_header가 하나도 없을 때만 server 블록의 add_header를 물려받습니다. noindex가 어떤 location 하나에만 들어 있을 수 있고, 그렇다면 server 블록에서 지워도 그대로 남습니다.
Apache:
Header set X-Robots-Tag "noindex, nofollow"
가상 호스트, 공용 include 파일, 문서 루트 안의 어느 .htaccess에든 있을 수 있습니다.
grep -rni 'x-robots-tag' /etc/apache2 /etc/httpd /var/www 2>/dev/null
스테이징 서버에서 복사해 온 설정이 대표적인 출처입니다. 누군가 스테이징이 구글에 안 잡히도록 noindex를 일괄로 넣었고, 그 파일이 운영 서버로 따라온 것입니다.
애플리케이션
웹 서버 설정이 깨끗하다면 애플리케이션이 직접 헤더를 붙이는 것입니다. 코드에서 찾아보세요.
grep -rni 'x-robots-tag' --exclude-dir=node_modules --exclude-dir=.git .
흔한 패턴은 환경 확인입니다. NODE_ENV나 APP_ENV가 production이 아니면 noindex를 붙이는 미들웨어가 있는데, 운영 환경 변수가 철자가 다르거나, 빠져 있거나, prod로 설정된 경우입니다. CMS와 SEO 플러그인 설정도 보세요. 워드프레스의 설정 → 읽기 → “검색 엔진이 이 사이트를 색인하지 않도록 합니다”는 헤더가 아니라 메타 robots noindex를 넣지만, 같은 이유로 오픈 뒤에도 켜진 채 남는 일이 많습니다. SEO 플러그인은 글 유형이나 보관함 전체를 noindex로 지정할 수 있습니다.
XML 사이트맵 파일에 noindex가 붙어 있는 것은 정상입니다. 일부 SEO 플러그인이 사이트맵 파일 자체가 검색 결과에 나오지 않도록 일부러 보내는 것이고, 그 파일에만 적용될 뿐 사이트맵에 적힌 URL에는 적용되지 않습니다.
robots.txt는 상황을 더 나쁘게 만듭니다
반사적으로 robots.txt에서도 그 URL을 막는 경우가 많습니다. 그러지 마세요. Disallow는 구글이 페이지를 가져가는 것 자체를 막으므로, 헤더가 아직 있는지 사라졌는지 볼 수 없게 됩니다. 색인에서 빼 주지도 않습니다. 막힌 URL도 그 URL을 가리키는 링크를 근거로 내용 없이 색인될 수 있습니다.
규칙은 간단합니다. 구글이 noindex를 따르게 하려면, 또는 noindex가 사라졌다는 걸 알아채게 하려면, 그 URL은 크롤링 가능해야 합니다.
3단계: 없애고 확인하기
- noindex를 붙이는 계층에서 지시를 없앱니다. 반대 헤더를 추가하지 마세요.
- 해당 URL의 CDN 캐시를 비웁니다.
- Googlebot User-Agent를 넣은 것과 뺀 것 둘 다 curl을 다시 돌립니다.
X-Robots-Tag헤더가 없거나, 있어도noindex가 없어야 합니다. - URL 검사에서 “실제 URL 테스트”를 실행합니다. 색인 생성 허용 여부가 “예”로 나와야 합니다.
- 가장 중요한 URL은 “색인 생성 요청”(Request indexing)을 누릅니다. 하루 할당량이 있으니 수백 개에 쓰지는 마세요.
- 영향받은 페이지가 많다면 페이지 색인 생성 보고서의 “‘noindex’ 태그에 의해 제외됨” 항목을 열고 수정 결과 검증(Validate fix)을 시작합니다. 그 URL들이
lastmod를 갱신한 채 사이트맵에 들어 있는지도 확인하세요.
검색에 다시 나오기까지
구글이 페이지를 다시 크롤링해야 변경이 반영됩니다. 그 시점은 구글이 내 사이트를 얼마나 자주 크롤링하느냐에 달려 있고, 직접 정할 수는 없습니다. 구글 안내로는 크롤링에 며칠에서 몇 주까지 걸릴 수 있습니다. 색인 생성 요청과 사이트맵은 구글이 URL을 다시 찾도록 도와줄 뿐, 언제 색인될지 또는 색인될지를 보장하지는 않습니다.
정말로 noindex가 필요한 곳이라면
스테이징과 프리뷰 환경에는 noindex보다 비밀번호 보호나 IP 허용 목록이 더 튼튼합니다. noindex는 설정 한 줄만 잘못 옮겨도 운영 서버로 새어 나가고, 이런 사고 대부분이 그렇게 시작됩니다. 인증은 내용을 비공개로 지켜 주기도 합니다.
다운로드 폴더의 PDF처럼 검색에 절대 나오지 않길 바라는 파일이라면 범위를 좁힌 규칙은 괜찮습니다.
location ~* \.pdf$ {
add_header X-Robots-Tag "noindex" always;
}
의도한 범위에만 걸리게 하고, 헤더를 건드리는 설정을 바꿀 때마다 curl로 다시 확인하세요.
함께 보면 좋은 글
- HTTP 보안 헤더: 헤더를 보는 김에 함께 확인할 만한 응답 헤더들.
- 301과 302 리다이렉트: noindex가 걸린 URL이 리다이렉트 체인에 있을 때.
- 도메인 이전 체크리스트: 스테이징의 noindex를 단 채 새 도메인을 여는 것은 이전을 망치는 흔한 방법입니다.
내 도메인에서 바로 확인
무료, 가입 불필요. 이 가이드가 다루는 항목을 바로 검사하고 조치 방법을 알려드립니다.