Gemini 웹 크롤링 실패 디버깅기: GOOGLE_EXTENDED_OPT_OUT의 진짜 의미를 찾아서
운영 중인 워드프레스 블로그의 글을 한꺼번에 요약하기 위해 Gemini에 다음과 같이 요청했다.
https://doyouknow.kr/
여기 글들 전부 가져와서 요약해줘.
하지만 Gemini는 사이트에 접근할 수 없다며 작업을 거부했다. 설명에 따르면 robots.txt 또는 사이트의 보안 설정 때문에 Google의 AI 크롤러가 차단됐고, 내부적으로 GOOGLE_EXTENDED_OPT_OUT이라는 결과를 받았다는 것이었다.
문제는 다른 도구와 일반 브라우저에서는 사이트가 정상적으로 열렸다는 점이다. 서버 관리자 입장에서는 정말 사이트 설정이 잘못된 것인지, Gemini의 웹 접근 기능에 문제가 있는 것인지 확인할 필요가 있었다.
이 글은 그 원인을 찾기 위해 robots.txt, Cloudflare, HTTP 응답 헤더, HTML 메타 태그, User-Agent, Google Apps Script까지 순서대로 점검한 기록이다.
먼저 결론부터
이번 점검으로 확인된 사실은 다음과 같다.
- 사이트의
robots.txt는 전체 크롤링을 허용하고 있었다. - 일반
curl요청은HTTP 200 OK를 반환했다. X-Robots-Tag: noindex,noai같은 차단 헤더는 확인되지 않았다.- HTML 문서에도 AI 크롤러를 명시적으로 차단하는 메타 태그가 없었다.
- Cloudflare의 AI 봇 관련 정책도 차단이 아닌 허용 상태였다.
- Google Apps Script의
UrlFetchApp에서도 사이트 접속에 성공했다. - 포스팅 작성 후 새 Gemini 채팅에서 같은 요청을 다시 실행했지만, 응답이 끝날 때까지 원본 서버 액세스 로그에는 요청이 한 건도 기록되지 않았다.
- 그런데도 Gemini의 URL 읽기 기능은 사이트 보안 설정 때문에 접근할 수 없었다고 답했다.
따라서 사이트가 Google-Extended를 명시적으로 차단하고 있다고 단정할 근거는 찾지 못했다.
또한 디버깅 도중 Gemini가 제시한 설명 중에는 공식 문서와 맞지 않는 내용도 있었다. 특히 Google-Extended를 실제 HTTP 요청에 사용되는 독립적인 User-Agent 문자열로 설명한 부분은 잘못됐다.
1. Gemini가 처음 제시한 원인: robots.txt 차단

Gemini는 처음부터 사이트의 robots.txt 또는 서버 정책이 AI 접근을 차단하고 있다고 설명했다.
실제 robots.txt는 다음과 같았다.
# START YOAST BLOCK # --------------------------- User-agent: * Disallow: # --------------------------- # END YOAST BLOCK
Disallow: 뒤에 경로가 비어 있으므로 모든 경로의 크롤링을 허용하는 설정이다.
즉, 최소한 현재 제공되는 robots.txt만 보면 전체 사이트를 막고 있지 않았다.
직접 확인하려면 다음 명령을 사용할 수 있다.
curl -i https://doyouknow.kr/robots.txt
본문만 간단히 확인하려면 다음과 같이 실행한다.
curl -s https://doyouknow.kr/robots.txt
여기까지 확인한 시점에서 robots.txt가 직접적인 원인이라는 첫 번째 가설은 제외할 수 있었다.
2. 실제 HTTP 응답 상태 확인
다음으로 사이트가 외부 요청에 정상적으로 응답하는지 확인했다.
curl -I https://doyouknow.kr/
응답은 다음과 같이 정상적인 200 OK였다.
HTTP/2 200
이 결과가 의미하는 것은 단순하다.
- DNS 조회가 정상적으로 이루어졌다.
- TLS 연결이 성공했다.
- 웹 서버 또는 CDN이 요청을 받아들였다.
- 최소한 해당 요청에 대해서는 접근 차단이 발생하지 않았다.
다만 여기서 주의할 점이 있다. 일반 curl 요청이 성공했다고 해서 Gemini 내부의 URL 가져오기 기능도 동일하게 성공해야 한다는 뜻은 아니다. 두 요청은 출발지 IP, User-Agent, 쿠키, 리다이렉트 처리, 캐시, 보안 정책 등이 다를 수 있다.
3. Cloudflare AI 봇 차단 여부 확인

Gemini는 다음 단계에서 Cloudflare의 AI 봇 차단 기능이 원인일 가능성이 높다고 설명했다.
Cloudflare에는 AI 크롤러를 행동 유형별로 차단하는 기능이 있다. 검색용 크롤러, 사용자 대신 실시간으로 작동하는 에이전트, 모델 학습용 크롤러 등을 각각 허용하거나 차단할 수 있다.
이에 따라 Cloudflare 대시보드에서 다음 항목들을 확인했다.
- AI 봇 정책
- Bot Fight Mode
- AI Labyrinth
- AI Scrapers and Crawlers 관련 설정
- 사용자 정의 WAF 규칙
- 특정 User-Agent 또는 ASN 차단 규칙
확인 결과 AI 봇 관련 정책은 차단이 아니라 허용 상태였고, 별도의 방화벽 차단 규칙도 발견하지 못했다.
따라서 현재 Cloudflare 설정만으로는 Gemini의 실패를 설명하기 어려웠다.
서버 관리자라면 Cloudflare 대시보드만 보는 데 그치지 말고 실제 보안 이벤트 로그도 함께 확인하는 것이 좋다. 요청이 Cloudflare까지 도달했다면 다음 정보가 남을 수 있다.
- 요청 시각
- 출발지 IP와 ASN
- User-Agent
- 적용된 WAF 규칙
- Bot Score
- 최종 조치가
Allow,Managed Challenge,Block중 무엇이었는지
가장 중요한 것은 Gemini가 실패한 바로 그 시각의 요청이 서버 또는 Cloudflare 로그에 존재하는지 확인하는 것이다.
로그에 요청 자체가 없다면, 요청은 사이트에 도달하기 전에 Gemini 또는 Google 내부 시스템에서 중단됐을 가능성이 있다.
4. HTTP 헤더의 X-Robots-Tag 확인
다음 가설은 워드프레스, 웹 서버 또는 SEO 플러그인이 HTTP 응답 헤더에 크롤링 제한을 추가하고 있다는 것이었다.
헤더 전체를 확인했다.
curl -sI https://doyouknow.kr/
특히 다음과 같은 값이 있는지 확인했다.
X-Robots-Tag: noindex X-Robots-Tag: nofollow X-Robots-Tag: nosnippet
필터링해서 확인하려면 다음 명령을 사용할 수 있다.
curl -sI https://doyouknow.kr/ \ | grep -i -E 'x-robots-tag|robots|google|ai'
점검 당시 응답에서는 AI 접근을 거부한다고 볼 수 있는 X-Robots-Tag가 발견되지 않았다.
여기서 X-Robots-Tag는 주로 검색 결과의 색인 및 노출 방식을 제어하는 HTTP 헤더다. robots.txt와는 적용 목적과 위치가 다르므로 별도로 확인해야 한다.
5. HTML 내부 robots 메타 태그 확인
HTTP 헤더가 정상이라도 HTML의 안에 다음과 같은 태그가 있을 수 있다.
다음 명령으로 HTML 본문에서 관련 태그를 검색했다.
curl -s https://doyouknow.kr/ \ | grep -i -E ']+(robots|googlebot|noindex|nosnippet)'
점검 당시 확인된 것은 일반적인 색인 허용 설정이었다.
Yoast SEO가 생성한 구조화 데이터 스크립트도 존재했지만, Yoast가 설치되어 있다는 사실만으로 AI 크롤러 차단을 의미하지는 않는다.
특히 다음과 같은 논리는 성립하지 않는다.
Yoast 관련 스크립트가 있으므로 Yoast가 보이지 않는 방식으로 Google-Extended를 차단하고 있을 것이다.
이를 주장하려면 실제 응답 차이, 플러그인 설정, 서버 로그 또는 재현 가능한 코드가 필요하다.
6. 잘못된 방향으로 진행된 Google-Extended User-Agent 테스트
Gemini는 자신이 다음과 같은 User-Agent로 접근한다고 설명하며 테스트 명령을 제시했다.
curl -s \ -H "User-Agent: Mozilla/5.0 (compatible; Google-Extended/1.0; +http://www.google.com/bot.html)" \ https://doyouknow.kr/
당시에는 이 요청도 정상적으로 성공했기 때문에 “Google-Extended User-Agent도 차단되지 않는다”고 판단했다.
하지만 공식 문서를 확인하면 이 테스트의 전제 자체가 잘못됐다.
Google 공식 문서에 따르면 Google-Extended는 독립적인 HTTP User-Agent 문자열을 갖고 있지 않다.
Google-Extended는 robots.txt에서 사용하는 제품 토큰(product token) 이다. 실제 크롤링 요청은 기존 Google 크롤러의 User-Agent로 이루어지며, Google-Extended는 이미 수집된 콘텐츠를 Gemini 모델 학습이나 일부 grounding 용도로 사용할 수 있는지를 제어한다.
따라서 위의 Google-Extended/1.0 문자열은 공식 Google 크롤러의 User-Agent를 재현한 것이 아니다. 단순히 임의의 문자열을 넣은 일반 HTTP 요청에 불과하다.
이 부분은 이번 디버깅에서 가장 중요한 교훈이었다.
도구가 제시한 User-Agent가 실제로 존재하는지 반드시 공식 문서에서 먼저 확인해야 한다.
7. GOOGLE_EXTENDED_OPT_OUT은 HTTP 상태 코드가 아니다
Gemini는 GOOGLE_EXTENDED_OPT_OUT을 사이트나 서버가 반환한 명시적인 상태처럼 설명했다.
하지만 실제 서버 응답을 확인했을 때 HTTP 상태는 200 OK였고, 응답 헤더나 HTML 본문에서도 GOOGLE_EXTENDED_OPT_OUT이라는 문자열은 확인되지 않았다.
HTTP 표준 상태 코드는 200, 403, 429, 500처럼 숫자로 표현된다. GOOGLE_EXTENDED_OPT_OUT은 서버가 반환한 표준 HTTP 상태 코드가 아니라 Gemini 또는 Google 내부 시스템에서 사용하는 결과명이나 정책 판단 메시지일 가능성이 높다.
따라서 다음 두 문장은 구분해야 한다.
사이트가 HTTP 403으로 요청을 거부했다.
Gemini 내부 도구가 GOOGLE_EXTENDED_OPT_OUT이라고 판단했다.
전자는 서버 응답으로 확인할 수 있는 사실이고, 후자는 Gemini 내부 처리 결과다. 내부 처리 결과만으로 서버 설정의 원인을 단정해서는 안 된다.
8. Google Apps Script로 테스트해 본 결과
Gemini는 구글 네트워크에서 요청을 보내면 자신의 환경과 비슷하게 재현할 수 있다며 Google Apps Script 테스트를 제안했다.
예시는 다음과 같다.
function checkSite() {
const url = "https://doyouknow.kr/";
const response = UrlFetchApp.fetch(url, {
method: "get",
muteHttpExceptions: true,
followRedirects: true
});
console.log("응답 코드: " + response.getResponseCode());
console.log("응답 길이: " + response.getContentText().length);
}실행 결과 사이트는 정상적으로 200 OK를 반환했다.
이 결과로 확인할 수 있는 것은 다음 정도다.
- Google Apps Script의
UrlFetchApp출발지에서 사이트에 접속할 수 있다. - 사이트가 모든 Google 소유 IP 대역을 일괄 차단하고 있지는 않다.
- 일반적인 HTTP 요청에는 정상적으로 응답한다.
그러나 이것 역시 Gemini의 내부 웹 검색 또는 URL 가져오기 기능을 그대로 재현한 것은 아니다.
Google Apps Script의 기본 User-Agent는 다음과 같은 별도의 문자열이다.
Mozilla/5.0 (compatible; Google-Apps-Script; beanserver; ...)
또한 Apps Script의 UrlFetchApp은 정해진 Google IP 풀에서 나가는 범용 HTTP 클라이언트다. Gemini의 브라우징, 검색 인덱스, grounding 또는 URL 처리 시스템과 동일하다고 볼 근거는 없다.
따라서 Apps Script가 성공했다고 해서 Gemini 내부 접근도 반드시 성공해야 하는 것은 아니다.
9. “구글 크롤링 캐시가 원인”이라는 결론은 입증되지 않았다
Gemini는 마지막으로 과거의 차단 이력이 Google 내부에 캐시되어 있어, 실제 서버에 요청하기도 전에 접근이 중단됐다고 설명했다.
Google 공식 문서에는 robots.txt가 일반적으로 최대 24시간 동안 캐시될 수 있다고 명시되어 있다. 네트워크 오류나 5xx 응답으로 새 파일을 가져오지 못하면 더 오래 유지될 수도 있다.
그러나 이 문서만으로 이번 문제의 원인이 robots.txt 캐시였다고 결론 내릴 수는 없다.
당시 확인하지 못한 항목은 다음과 같았다.
- Gemini가 실제로 어떤 Google 크롤러 또는 fetcher를 사용하는지
- 요청이 Cloudflare 또는 다른 중간 계층까지 도달했는지
- 어떤 robots.txt 사본을 참조했는지
- 내부 캐시의 생성 시각과 TTL
GOOGLE_EXTENDED_OPT_OUT판정의 정확한 조건- Gemini 공유 대화에서 URL 접근에 사용된 내부 도구의 종류
즉, “캐시일 수도 있다”는 가설은 가능하지만, “캐시가 범인이다”라고 확정할 증거는 없었다.
10. 포스팅 작성 이후 추가 확인: 원본 서버에는 요청이 도달하지 않았다

포스팅을 작성한 뒤 재현성을 확인하기 위해 새 Gemini 채팅 세션을 열고 처음과 동일한 요청을 다시 보냈다.
그와 동시에 원본 웹 서버의 액세스 로그를 실시간으로 관찰했다. 일반적인 NGINX 환경이라면 다음과 같은 방식으로 확인할 수 있다.
sudo tail -F /var/log/nginx/access.log
내가 Gemini에 메시지를 보낸 시점부터 Gemini가 아래 답변을 완료할 때까지 로그를 계속 지켜봤다.
웹사이트에 접속을 시도했으나, 해당 사이트의 보안 설정이나 접근 제한(AI 봇 및 검색 엔진의 접근 차단)으로 인해 내용을 읽어올 수 없었습니다.
그러나 그 시간 동안 원본 서버의 액세스 로그에는 새로운 요청이 단 한 건도 기록되지 않았다.
실제로 원본 서버까지 HTTP 요청이 도달했다면 보통 GET, HEAD 등의 요청 경로, User-Agent, 응답 상태 코드가 액세스 로그에 남아야 한다. 로그가 깨끗했다는 것은 적어도 이번 재현 시도에서는 Gemini의 요청이 원본 서버까지 도달하지 않았다는 뜻이다.
이 관찰로 가능한 시나리오는 다음과 같이 좁혀진다.
- Gemini가 실제 네트워크 요청을 보내기 전에 검색 인덱스나 내부 정책 정보만으로 접근 불가 판정을 내렸다.
- 요청이 Google 내부 시스템 또는 CDN 같은 중간 계층에서 종료되어 원본 서버까지 전달되지 않았다.
- Gemini가 사용자에게 “접속을 시도했다”고 표현했지만, 실제 외부 HTTP 요청은 발생하지 않았다.
다만 원본 서버 액세스 로그만으로 Cloudflare 엣지까지 요청이 도달했는지는 알 수 없다. Cloudflare에서 차단된 요청은 원본 서버 로그에 남지 않을 수 있기 때문이다. 따라서 같은 시각의 Cloudflare Security Events와 HTTP 로그까지 비어 있었다면, Gemini 내부에서 원본 요청 자체를 만들지 않았을 가능성은 더욱 커진다.
중요한 점은 다음과 같다.
Gemini는 사이트의 보안 설정 때문에 내용을 읽지 못했다고 답했지만, 원본 서버에서는 그 주장을 뒷받침할 실제 접근 시도가 관찰되지 않았다.
따라서 현재까지의 가장 정확한 결론은 다음과 같다.
사이트의 공개 설정과 외부 HTTP 응답에서는 차단 근거를 찾지 못했다. 새 채팅에서 재현했을 때에도 요청은 원본 서버에 도달하지 않았다. Gemini의 URL 접근 실패는 서버의 응답을 받은 뒤 발생한 것이 아니라, 원본 서버에 도달하기 전 내부 처리 단계에서 발생했을 가능성이 높다. 다만 그 내부 단계가 검색 인덱스, 정책 캐시, URL 안전성 검사 또는 다른 시스템 중 무엇인지는 공개된 정보만으로 확인할 수 없다.
11. 실제로 확정할 수 있는 것과 없는 것
확정할 수 있는 것
- 점검 당시
robots.txt의Disallow:값은 비어 있었다. - 일반
curl요청은HTTP 200 OK를 받았다. - 응답 헤더에 명시적인
X-Robots-Tag차단 값이 없었다. - HTML 본문에서
noindex또는 AI 차단용으로 의심되는 메타 태그를 찾지 못했다. - Cloudflare 대시보드의 AI 봇 정책은 허용 상태였다.
- Google Apps Script에서도 HTTP 요청이 성공했다.
- 새 Gemini 채팅에서 같은 요청을 재현하는 동안 원본 서버 액세스 로그에는 요청이 기록되지 않았다.
- Gemini는 원본 서버 요청이 관찰되지 않았음에도 사이트의 보안 설정과 접근 제한 때문에 실패했다고 답했다.
확정할 수 없는 것
- Gemini가 실제 외부 요청을 만들었다면 어떤 IP와 User-Agent를 사용했는지
- 요청이 Cloudflare 엣지 또는 Google 내부의 어느 단계까지 진행됐는지
GOOGLE_EXTENDED_OPT_OUT이 정확히 어떤 내부 조건에서 발생하는지- 과거 robots.txt 또는 정책 캐시가 실제 원인이었는지
- Gemini가 검색 인덱스, 실시간 fetcher, 브라우저 에이전트 중 무엇을 사용했는지
12. 비슷한 문제를 만났을 때의 점검 순서
AI 서비스가 특정 URL을 읽지 못한다고 할 때는 추측보다 계층별로 증거를 수집하는 편이 빠르다.
1단계: robots.txt 확인
curl -i https://example.com/robots.txt
확인할 항목:
- HTTP 상태 코드
- 리다이렉트 여부
User-agent: *규칙Googlebot,Google-Extended등 개별 그룹- CDN이 robots.txt를 덮어쓰고 있는지
2단계: 일반 페이지 응답 확인
curl -sSIL https://example.com/
확인할 항목:
- 최종 상태 코드
- 리다이렉트 체인
Server,Via,CF-RayX-Robots-Tag- 캐시 관련 헤더
3단계: HTML 메타 태그 확인
curl -sSL https://example.com/ \ | grep -i -E ']+(robots|googlebot|noindex|nosnippet)'
4단계: CDN 및 WAF 이벤트 확인
- Cloudflare Security Events
- Bot Analytics
- AI Crawl Control
- 사용자 정의 WAF 규칙
- Rate Limiting
- 원본 서버 접근 로그
5단계: 요청 도달 여부 확인
가장 결정적인 질문은 이것이다.
실패한 시각에 해당 AI 서비스의 요청이 서버 로그에 남았는가?
- 로그가 있다면 서버 또는 CDN 응답을 분석한다.
- 로그가 없다면 AI 서비스 내부에서 요청이 중단됐을 가능성을 고려한다.
6단계: 공식 User-Agent 문서 확인
블로그 글이나 AI 답변에서 본 User-Agent 문자열을 바로 믿지 말고 해당 업체의 공식 크롤러 문서에서 확인한다.
7단계: 재현 테스트의 한계 기록
curl, 브라우저, 서버리스 함수, Google Apps Script가 성공하더라도 대상 AI 제품의 내부 fetcher와 동일한 환경은 아닐 수 있다.
테스트 결과에는 항상 다음 문장을 붙이는 것이 좋다.
이 테스트는 네트워크 접근 가능성을 확인한 것이며, 대상 AI 제품의 내부 URL 처리 경로를 완전히 재현하지는 않는다.
13. 이번 디버깅에서 배운 점
AI의 자신감과 사실성은 별개다
Gemini는 원인을 여러 번 확정적으로 설명했다.
- robots.txt가 차단했다.
- Cloudflare가 Google IP를 차단했다.
- Yoast가 동적으로 메타 태그를 삽입했다.
- Google 내부 캐시가 남아 있다.
하지만 점검할 때마다 앞선 설명과 다른 결과가 나왔다. 설명은 구체적이었지만 이를 뒷받침하는 실제 증거는 부족했다.
기술적인 답변에서 중요한 것은 그럴듯함이 아니라 검증 가능성이다.
서버 응답과 AI 내부 판단을 구분해야 한다
HTTP 200, 403, 응답 헤더, 접근 로그는 서버 측 증거다.
반면 GOOGLE_EXTENDED_OPT_OUT 같은 문구는 AI 제품 내부의 정책 판단 또는 오류 표현일 수 있다. 둘을 같은 것으로 취급하면 디버깅 방향이 잘못된다.
Google-Extended는 독립 HTTP User-Agent가 아니다
이번 과정에서 가장 명확하게 잘못 알려진 부분이다.
Google-Extended는 robots.txt에서 콘텐츠 사용 범위를 관리하기 위한 제품 토큰이며, 별도의 HTTP 요청 User-Agent 문자열은 없다.
따라서 Google-Extended/1.0을 User-Agent로 넣은 curl 요청은 실제 Google-Extended 요청을 재현하지 않는다.
“가능성”과 “결론”을 구분해야 한다
robots.txt 캐시가 존재한다는 공식 문서와, 이번 장애가 그 캐시 때문에 발생했다는 주장은 별개의 문제다.
공식 문서가 어떤 메커니즘의 존재를 설명한다고 해서 개별 장애의 원인까지 자동으로 입증되는 것은 아니다.
마무리
이번 문제에서 사이트 자체의 명시적인 차단 설정은 찾지 못했다. 서버는 일반 브라우저, curl, Google Apps Script 요청에 모두 정상적으로 응답했다.
포스팅 작성 후 새 채팅에서 동일한 요청을 다시 실행하며 원본 서버의 액세스 로그를 관찰했지만, Gemini가 접근 실패를 답변할 때까지 서버에는 요청이 한 건도 들어오지 않았다. 적어도 이 재현에서는 서버가 요청을 거부한 것이 아니라, 요청이 원본 서버에 도달하기 전에 Gemini 내부 처리 단계에서 중단된 것으로 보는 편이 타당하다.
반면 Gemini는 사이트를 읽지 못했고, 그 원인을 설명하는 과정에서 확인되지 않은 가설을 사실처럼 제시했다. 특히 존재하지 않는 Google-Extended 전용 HTTP User-Agent를 안내하고, 충분한 증거 없이 Google 내부 캐시를 최종 원인으로 단정한 점은 아쉬웠다.
결국 이 사례는 단순한 크롤링 장애라기보다 다음 원칙을 다시 확인하게 만든 디버깅 사례였다.
AI가 제시한 기술적 설명은 출발점으로 활용할 수 있지만, 최종 결론은 반드시 실제 HTTP 응답, 서버 로그, 설정 화면, 공식 문서로 검증해야 한다.
