카톡·스레드 링크 미리보기가 안 뜰 때 확인 순서: og:image 용량, 크롤러 UA, Cloudflare AI 봇 차단
og 태그가 멀쩡한데도 카카오톡과 스레드에서 링크 미리보기가 안 뜬 사이트를 curl로 크롤러 응답을 재현해 고친 과정입니다. 원인 세 가지와 각각 확인하는 명령, 고친 뒤에도 안 되는 것을 정리했습니다.
운영하는 사이트의 글 링크를 카톡 방에 공유했는데 미리보기 카드가 안 떴습니다. 제목만 파랗게 나오고 이미지도 설명도 없는 링크였습니다. 소스를 열어 보니 og:title, og:description, og:image 는 전부 들어 있었고, 원인은 세 개였는데 셋 다 사이트 코드 바깥에 있었습니다. 카카오는 og:image 가 500KB를 넘으면 이미지를 안 띄우고, 서버의 봇 UA 목록에 meta-externalagent 가 없으면 스레드·인스타 크롤러가 빈 화면을 받아 가고, Cloudflare의 AI 봇 차단이 켜져 있으면 그 크롤러가 403을 받습니다. 아래는 이 셋을 어떤 순서로 확인했는지와 각각 무엇을 고쳤는지입니다.

링크 미리보기 확인은 브라우저가 아니라 curl로 한다
브라우저로 열면 페이지가 멀쩡히 그려지니 아무 단서가 안 나옵니다. 미리보기 카드를 만드는 건 카카오·메타 같은 서비스의 크롤러이고, 크롤러가 받는 HTML은 내가 브라우저에서 보는 것과 다를 수 있습니다. 그래서 크롤러의 UA를 붙여 직접 요청하고, 응답에 og: 태그가 실제로 들어 있는지를 봤습니다.
# 페이스북/스레드 계열 크롤러를 흉내 내 요청하고 og 태그만 추린다
curl -sA "meta-externalagent" https://example.com/posts/hello | grep -i 'og:'
이 명령이 진단 내내 기준점이었습니다. og: 줄이 여러 개 잡히면 서버는 제대로 응답한 것이고, 하나도 안 잡히면 크롤러가 빈 껍데기를 받고 있다는 뜻입니다. 카카오 UA로 볼 때는 -A 값만 kakaotalk-scrap 으로 바꿉니다.
앞단에 Cloudflare 같은 프록시가 있으면 두 군데를 따로 확인하는 게 좋습니다. 내 PC에서 봇 UA로 Cloudflare를 거쳐 요청하면 봇 대응 기능 때문에 빈 응답이 올 수 있어서, 결과가 이상하면 서버 안에서 curl --resolve 도메인:443:127.0.0.1 로 오리진을 직접 불러 비교합니다. 둘 다 og 태그가 나오면 서버는 정상이고, 오리진에서만 나오면 앞단이 막고 있는 것입니다.
curl 결과로 원인 세 가지 가르기
| curl 결과 | 의심할 곳 | 고친 것 |
|---|---|---|
| og 태그는 있는데 카톡 이미지만 없음 | 이미지 용량 | PNG → JPEG, 500KB 아래로 |
| og 태그가 하나도 없음 | nginx 봇 UA 목록 | meta-externalagent 추가 |
| HTML 대신 403 | Cloudflare AI 봇 차단 | 차단 범위를 Do not block |
안쪽(이미지)에서 바깥쪽(방화벽)으로 차례로 보면 됩니다. 이 사이트도 이 순서로 하나씩 걷어냈습니다.
카카오톡 미리보기 이미지가 안 뜰 때: og:image 500KB
curl 로 보니 og:image 태그는 응답에 들어 있었습니다. 태그가 있는데 카톡에서 이미지가 안 뜬다면 카카오가 이미지를 받아 놓고 쓰지 않는 쪽입니다. 이미지 URL을 직접 열어 용량을 재 보니, PNG로 만든 대표 이미지가 1MB를 넘고 있었습니다.
카카오는 og:image 가 500KB를 넘으면 미리보기 이미지를 띄우지 않습니다. 글자가 많은 썸네일을 PNG로 뽑으면 1MB를 쉽게 넘깁니다. 같은 이미지를 JPEG 품질 90으로 다시 뽑았더니 눈으로는 차이가 거의 없고 용량은 150~250KB로 내려갔습니다.
이미지를 바꿨는데 예전 미리보기가 계속 나올 때
카카오는 한 번 가져간 이미지 URL을 캐시해 두기 때문에, 같은 파일명으로 덮어쓰면 예전 결과를 계속 보여 줄 수 있습니다. 그래서 이미지를 교체할 때 파일명을 바꿔 URL 자체를 다르게 만들었습니다(.png 를 .jpg 로 바꾼 것만으로도 URL이 달라집니다). 새 URL이라 카카오가 새로 가져갔고, 그때 카톡 미리보기가 떴습니다. 이미지 파일명을 못 바꿀 때는 공유하는 페이지 주소 뒤에 한 번도 공유한 적 없는 쿼리(?v=2 같은)를 붙여 다시 공유해도 카카오가 새로 가져갑니다.
메타 쪽도 사정이 같습니다. 메타 공식 문서는 이미지가 URL 기준으로 캐시되고 URL이 바뀌기 전에는 갱신되지 않는다고 적고 있습니다. 메타는 공유 디버거에 주소를 넣으면 크롤러가 읽은 태그를 보여 주고 다시 가져가게 할 수 있습니다. 카카오에도 카카오 디벨로퍼스의 공유 디버거가 있지만 개발자 계정 로그인이 필요해서, 로그인 없이 바로 확인하려면 위 curl 이 제일 빠릅니다.
서버가 막혀 있는 동안 크롤러가 먼저 가져가면 “이미지 없음” 상태가 캐시된다는 점도 조심해야 합니다. 아래 두 원인까지 다 고친 뒤에 새 URL로 다시 공유해야 깨끗하게 뜹니다.
스레드·인스타 미리보기가 안 뜰 때: nginx 봇 UA 목록에 meta-externalagent 추가
카톡은 해결됐는데 스레드와 인스타그램에서는 여전히 안 떴습니다. curl 로 보니 이번에는 응답에 og: 태그가 하나도 없었습니다. 크롤러가 og 태그가 담긴 페이지가 아니라 빈 SPA 셸을 받고 있었습니다.
이 사이트는 SPA라서 일반 방문자에게는 자바스크립트로 내용을 채우는 빈 HTML을 보냅니다. 크롤러는 자바스크립트를 실행하지 않기 때문에, nginx 앞단에서 UA를 보고 크롤러면 미리 렌더링해 둔(프리렌더) HTML을 대신 내주는 구조를 씁니다. 이 분기는 “이 UA는 크롤러다”라는 목록으로 정해지고, 목록에 없는 UA는 일반 방문자로 취급돼 빈 셸을 받습니다. 목록에 meta-externalagent 가 없었고, 한 줄을 추가했습니다.
# 봇 UA면 프리렌더 서버로, 아니면 SPA 셸로 보낸다
map $http_user_agent $is_bot {
default 0;
"~*facebookexternalhit" 1;
"~*meta-externalagent" 1; # 스레드·인스타 크롤러의 새 UA
"~*kakaotalk-scrap" 1;
"~*twitterbot" 1;
}
server {
location / {
if ($is_bot) {
proxy_pass http://prerender_upstream;
break;
}
try_files $uri /index.html; # 일반 방문자는 SPA 셸
}
}
메타 공식 크롤러 문서에는 링크 미리보기용 facebookexternalhit 말고도 meta-externalagent, meta-externalfetcher 같은 크롤러가 여럿 올라 있습니다(2026년 10월 확인). 크롤러 이름은 예고 없이 늘어나니 이 목록은 한 번 짜고 끝나는 게 아니라 가끔 다시 봐야 합니다. nginx 설정이 자동 배포에 들어 있지 않다면 고친 뒤 서버에서 nginx -t && systemctl reload nginx 로 문법을 확인하고 다시 읽어 들여야 반영됩니다.
403이 돌아올 때: Cloudflare Block AI bots
UA를 추가했는데도 스레드에서 안 떴습니다. curl -A "meta-externalagent" 로 다시 요청하니 HTML 대신 403 이 돌아왔습니다. 요청이 nginx까지 가지도 못하고 앞단의 Cloudflare에서 막히고 있었습니다.
원인은 Cloudflare의 Block AI bots 기능이었습니다. 이 기능이 meta-externalagent 를 AI 학습용 크롤러로 분류해 403을 돌려주고 있었습니다. 메타 공식 문서도 meta-externalagent 를 AI 모델 학습 같은 용도로 웹을 긁는 크롤러라고 설명하고 있어서, Cloudflare가 잘못 분류했다기보다는 같은 크롤러가 미리보기에도 쓰이고 있던 겁니다.
이 크롤러만 통과시키려면 WAF에서 Skip 규칙을 만들면 되는데, 무료 플랜에서는 이 규칙으로 AI 봇 차단을 건너뛸 수 없었습니다. 그래서 대시보드에서 Block AI bots의 차단 범위를 “Do not block”으로 내렸습니다. 그 뒤 curl 응답에 og 태그가 다시 잡혔고, 스레드에서도 미리보기가 떴습니다.
메뉴 위치는 그사이 바뀌었습니다. Cloudflare 문서 기준으로 예전 Block AI bots 설정은 2026년 9월 15일 지원 종료로 표시돼 있고, Security Settings의 Configure AI bot policies에서 Search·Agent·Training 범주별로 “Allow (do not block)“을 고르는 방식으로 넘어갔습니다(2026년 10월 확인).
고친 뒤에도 안 되는 것
- 특정 크롤러 하나만 AI 봇 차단에서 빼는 건 무료 플랜에서 할 수 없었습니다. 범위를 낮추면 다른 AI 학습 크롤러도 같이 통과합니다.
- 카카오 캐시를 지우려면 로그인이 필요한 공유 디버거를 쓰거나 URL을 바꿔야 합니다. 이미 공유된 예전 URL은 캐시가 만료될 때까지 그대로 남습니다.
nginx 앞단에서 응답이 이상해지는 다른 경우는 컨테이너를 다시 만들면 nginx가 502를 내는 이유에, Cloudflare를 앞단에 두는 구성은 포트포워딩 없이 집 서버를 여는 Cloudflare Tunnel에 적어 두었습니다.
자주 묻는 질문
카카오톡 링크 미리보기 이미지가 안 뜨는 이유는 뭔가요?
og:image 파일이 500KB를 넘으면 카카오는 미리보기를 아예 띄우지 않습니다. PNG로 만들면 1MB를 쉽게 넘기니 JPEG 품질 90으로 150~250KB까지 낮추면 뜹니다. 파일명을 함께 바꾸면 카카오의 캐시도 비껴갈 수 있습니다.
스레드·인스타그램 크롤러의 User-Agent는 무엇인가요?
메타 계열 크롤러의 UA가 meta-externalagent로 바뀌었습니다. nginx에서 봇 UA 화이트리스트로 프리렌더를 분기한다면 이 이름을 목록에 추가해야 SPA 셸 대신 og 태그가 담긴 HTML을 응답합니다.
meta-externalagent가 UA 목록에 있는데도 미리보기가 안 뜨면요?
Cloudflare의 Block AI bots 기능이 meta-externalagent를 AI 크롤러로 분류해 403을 돌려줄 수 있습니다. 무료 플랜은 WAF Skip 규칙을 만들 수 없어 대시보드에서 차단 범위를 Do not block으로 내려야 통과합니다.
미리보기가 뜨는지 어떻게 확인하나요?
curl -A로 크롤러 UA를 붙여 직접 요청하고 응답 HTML에 og: 태그가 들어 있는지 확인합니다. 카카오는 별도 디버거가 없어 이 방식이 사실상 유일한 확인 수단입니다.