birchholt 직접 해보고 남기는 기록

구글 검색결과에 내 블로그 파비콘이 안 뜬다면: favicon.ico가 404였고, '48px 배수'는 지금 기준이 아니었습니다

구글 검색결과에서 사이트 이름 옆 작은 동그라미에 기본 아이콘만 나온다는 질문은 검색 센터 커뮤니티에도 올라와 있습니다. 그 자리에 들어가는 그림이 파비콘(favicon, 브라우저 탭이나 검색결과에서 사이트를 나타내는 작은 아이콘)입니다. 제 블로그도 확인해 보려고 찾아보니 “48px의 배수로 만들어야 한다"는 답이 달려 있었습니다.

숲길 이정표 기둥들 가운데 하나에만 새김 판이 비어 있는 갈림길

그런데 제 경우에는 크기가 문제가 아니었습니다. 파일이 아예 없었습니다. 그리고 그 48px 규칙도 지금 구글 문서에는 없는 문구였습니다. Hugo v0.165.0, Cloudflare Pages 환경에서 2026-10-07에 확인한 내용입니다.

먼저 제 사이트에 무엇이 없었는지 봤습니다

빈 액자 고리만 남은 현관 벽을 손전등으로 비춰 보는 사람

먼저 흔히 쓰는 파비콘 파일 이름을 운영 주소에 전부 찍어 봤습니다.

$ for u in /favicon.ico /favicon.svg /favicon.png /apple-touch-icon.png; do
    curl -s -o /dev/null -w "$u %{http_code} %{content_type}\n" "https://birchholt.com$u"; done
/favicon.ico 404 text/html; charset=utf-8
/favicon.svg 404 text/html; charset=utf-8
/favicon.png 404 text/html; charset=utf-8
/apple-touch-icon.png 404 text/html; charset=utf-8

네 개 모두 404였습니다. /favicon.ico 본문을 열어 보니 제 사이트의 “주소를 찾지 못했습니다” 페이지였습니다. (이 404 페이지를 만들게 된 사연은 없는 주소가 200을 돌려주던 일에 적었습니다.)

홈 HTML에서 아이콘을 지정하는 <link rel="icon"> 태그도 찾아봤는데 0개였습니다. 저장소의 static/ 폴더(Hugo가 손대지 않고 그대로 사이트 루트에 복사하는 폴더)에는 _headers, robots.txt 같은 설정 파일뿐이었고 아이콘 파일은 없었습니다. 사이트를 만들면서 파비콘을 한 번도 안 넣은 겁니다.

robots.txt(크롤러에게 어디를 읽어도 되는지 알려주는 파일)는 Allow: /라서 막힌 곳은 없었습니다.

구글이 지금 어떤 아이콘을 들고 있는지 보려고 구글의 파비콘 이미지 주소(t0.gstatic.com/faviconV2)도 찔러 봤습니다. 제 도메인은 404와 함께 16×16 기본 아이콘이 돌아왔고, 대조군으로 넣은 gohugo.io는 200과 64×64 아이콘이 돌아왔습니다. 다만 이 주소는 공개 문서가 없어서 검색결과와 같은 데이터를 본다는 근거는 없습니다. 반영 날짜를 매일 기록할 때 보조 지표로만 씁니다.

‘48px의 배수’는 2024년 말에 바뀐 옛 문구입니다

오래된 규격 자와 새 규격 자를 작업대에 나란히 대 보는 목수의 손

검색 센터 커뮤니티의 한국어 질문을 두 개 읽었습니다. 하나는 파비콘을 16×16으로 올렸는데 몇 주째 안 나온다는 질문(2024-11-12)입니다. 추천 답변은 문서를 인용해 “파비콘은 너비/높이가 48px의 배수인 정사각형이어야 합니다"라고 했습니다.

지금 구글 문서의 문장은 다릅니다.

Your favicon must be a square (1:1 aspect ratio) that’s at least 8x8px. While the minimum size requirement is 8x8px, we recommend using a favicon that’s larger than 48x48px

필수 조건은 정사각형이고 8×8 이상인 것이고, 48×48보다 큰 것은 권장입니다. 배수 조건은 없습니다.

언제 바뀌었는지 인터넷 아카이브(Wayback Machine)에 남은 문서 사본을 날짜별로 열어 봤습니다.

사본 날짜     크기 문구                       문서의 최종 업데이트
2024-06-01   must be a multiple of 48px    2024-04-29
2024-11-01   must be a multiple of 48px    2024-08-28
2024-12-03   larger than 48x48px           2024-10-31
2026-10-01   larger than 48x48px           2026-02-04

최종 업데이트 날짜가 2024-10-31인 판에서 바뀌었습니다. 다만 2024-11-01 사본까지는 옛 문구였으니 실제로 공개된 날은 11월 초에서 12월 초 사이 어딘가입니다. 사본 간격 때문에 정확한 날짜는 확인하지 못했습니다. 위 커뮤니티 답변(2024-11-12)이 옛 문구를 인용한 것도 이 전환 무렵이었습니다. 그 질문의 16×16 파일은 지금 기준으로는 최소 조건을 넘습니다. 다만 권장 크기에는 못 미칩니다.

두 달 뒤 올라온 질문(2025-01-09)의 답변자는 “작년 중반만 하더라도 필요조건으로 했었습니다"라고 적었습니다. 아카이브로 보면 필수 문구는 그해 가을까지 남아 있었습니다.

SVG 하나만 두면 안 되는 이유도 문서에 있었습니다

여러 모양의 열쇠 중 몇 개만 맞는 열쇠 구멍 앞에서 꾸러미를 고르는 사람

요즘 정적 사이트 예제는 favicon.svg 한 장만 두는 경우가 많습니다. 옛 문서에는 “Any valid favicon format is supported”, 즉 유효한 형식이면 다 된다고 적혀 있었습니다.

그런데 2026-10-07에 연 현행 문서(최종 업데이트 2026-08-28)에는 형식 목록이 있습니다.

Google Search supports the following favicon file formats: BMP, GIF, ICO, PNG, JPEG, PPM, and TIFF.

SVG가 목록에 없습니다. 그래서 저는 ICO와 PNG를 기본으로 두기로 했습니다.

2026-10-01 아카이브 사본에는 아직 옛 문구가 남아 있었습니다. 사본이 늦게 갱신된 것일 수도 있어서 목록이 생긴 정확한 날짜는 확인하지 못했습니다. 확실한 것은 지금 문서에 SVG가 없다는 점입니다.

같은 문서의 다른 조건도 적어 둡니다.

Hugo에서는 static에 세 파일, head에 세 줄이면 됩니다

묘목 세 그루를 정원 입구 화단에 나란히 심고 팻말 고리를 거는 정원사

운영 저장소는 그대로 두고 사본에서 작업했습니다. 파일은 세 개를 만들었습니다. 사이트 색에 맞춰 세이지 초록 바탕에 자작나무 줄기를 그렸습니다.

static/favicon.ico           814 B   16·32·48px 세 장을 담은 ICO
static/favicon-96x96.png     569 B   96×96
static/apple-touch-icon.png 1152 B   180×180 (iOS 홈 화면용)

96×96은 48×48보다 크다는 권장 조건을 맞춘 크기입니다. ICO에 16·32·48을 같이 넣은 것은 브라우저 탭용입니다.

그리고 일반 페이지가 함께 쓰는 layouts/_partials/head.html에 세 줄을 넣었습니다.

<link rel="icon" type="image/png" sizes="96x96" href="{{ "favicon-96x96.png" | relURL }}">
<link rel="icon" href="{{ "favicon.ico" | relURL }}" sizes="16x16 32x32 48x48">
<link rel="apple-touch-icon" href="{{ "apple-touch-icon.png" | relURL }}">

제 사이트는 CSS 파일 이름에 내용 해시를 붙이는 fingerprint를 쓰는데 파비콘에는 일부러 안 붙였습니다. 붙이면 그림을 고칠 때마다 주소가 바뀌고 그건 구글이 하지 말라고 한 일입니다.

빌드 결과를 패치 전과 비교했습니다.

패치 전  public/favicon*  없음      홈의 rel=icon  0개
패치 후  public/favicon.ico 등 3개  홈의 rel=icon  3줄
         HTML 34개 중 24개에 link 포함

빠진 10개는 전부 예전 주소를 새 주소로 넘겨주는 리다이렉트용 페이지였습니다. 구글이 보는 것은 홈이라 문제없습니다.

Cloudflare Pages에 올려 응답을 확인했습니다

숲속 우체국 창구에서 소포 꼬리표를 하나씩 확인하는 직원

로컬에 파일이 있는 것과 호스팅이 그 파일을 제대로 내주는 것은 별개입니다. 그래서 운영 주소가 아닌 미리보기 배포(Cloudflare Pages가 브랜치마다 따로 만들어 주는 임시 주소)에 올려 찍어 봤습니다.

$ curl -s -o /dev/null -w '%{http_code} %{content_type} %{size_download}\n' "$PREVIEW/favicon.ico"
200 image/vnd.microsoft.icon 814
$ curl -sI "$PREVIEW/favicon.ico" | grep -i cache-control
cache-control: public, max-age=0, must-revalidate
$ curl -s -A "Googlebot-Image/1.0" -o /dev/null -w '%{http_code} %{content_type}\n' "$PREVIEW/favicon.ico"
200 image/vnd.microsoft.icon

미리보기 응답에는 x-robots-tag: noindex도 붙어 있었습니다. 이건 제가 pages.dev 주소가 검색에 안 잡히게 해 둔 설정 때문입니다. 그 규칙은 *.pages.dev 주소에만 걸려 있어서 운영 도메인에는 해당하지 않습니다. 확인이 끝난 뒤 미리보기 배포는 지웠습니다.

검색결과 아이콘은 아직 바뀌지 않았습니다

창가 달력에 매일 아침 작은 잎사귀 스티커를 하나씩 붙여 나가는 손

문서는 기다리는 시간을 이렇게 적습니다.

Remember that crawling can take anywhere from several days to several weeks, depending on how often our systems determine content needs to be refreshed. You can request indexing of your site’s home page by using the URL Inspection tool.

며칠에서 몇 주이고 Search Console의 URL 검사에서 홈 주소로 색인 생성을 요청할 수 있다는 뜻입니다. 앞의 2025년 커뮤니티 답변에는 “몇 달씩 이나 업데이트하지 않은 사례도 종종 있습니다"라는 말도 있었습니다. 문서에도 조건을 다 지켜도 표시가 보장되지는 않는다고 적혀 있습니다.

운영 저장소에 반영하고 배포가 끝난 뒤, 2026-10-07 새벽에 운영 주소를 다시 찍었습니다.

$ for u in /favicon.ico /favicon-96x96.png /apple-touch-icon.png; do
    curl -s -o /dev/null -w "$u %{http_code} %{content_type} %{size_download}\n" "https://birchholt.com$u"; done
/favicon.ico 200 image/vnd.microsoft.icon 814
/favicon-96x96.png 200 image/png 569
/apple-touch-icon.png 200 image/png 1152
$ curl -s https://birchholt.com/ | grep -oE '<link[^>]*icon[^>]*>'
<link rel=icon type=image/png sizes=96x96 href=/favicon-96x96.png>
<link rel=icon href=/favicon.ico sizes="16x16 32x32 48x48">
<link rel=apple-touch-icon href=/apple-touch-icon.png>

미리보기와 다른 점이 하나 있었습니다. 운영 도메인의 파비콘은 cache-control: public, max-age=14400, must-revalidate였습니다. 브라우저가 최대 4시간 동안 서버에 묻지 않고 예전 그림을 쓸 수 있다는 뜻입니다. 같은 도메인의 robots.txt도 14400이었고 홈 HTML은 max-age=0이었습니다. 그림을 바꾼 직후 탭 아이콘이 그대로라면 이 캐시를 먼저 의심하면 됩니다.

검색결과 쪽은 아직 확인하지 못했습니다. 이 글을 쓰는 시점에는 Search Console에서 홈 주소로 색인 생성을 요청하지 않았고 검색결과의 아이콘이 바뀌는 것도 보지 못했습니다. 그래서 이 글이 확인한 범위는 “구글이 읽을 파일과 태그를 제대로 내놓았다"까지이고 검색결과에 실제로 언제 뜨는지는 아닙니다. 확인은 이렇게 할 생각입니다.

앞에서 쓴 faviconV2 주소는 반영 직후에도 404와 16×16 기본 아이콘을 돌려줬습니다. 대조군 gohugo.io는 여전히 200과 64×64였습니다. 공개 문서가 없는 주소라서 이 값이 바뀌어도 검색결과가 바뀌었다는 증거로 쓰지는 않고, 날짜별 기록의 보조 칸으로만 둡니다.

같은 일이 다시 생기지 않게 배포 워크플로(배포할 때 자동으로 도는 작업 절차)에 검사도 넣었습니다. 사본에서 먼저 돌려 본 뒤 운영 워크플로에 붙였고 그 배포가 이 검사를 통과해 성공했습니다. 빌드 결과에 favicon.ico가 있는지, 홈에 rel=icon이 있는지 보고 배포 뒤에는 운영 주소의 파비콘이 200인지 찍는 검사입니다.

test -f public/favicon.ico || { echo "🔴 favicon.ico 가 없다" >&2; exit 1; }
grep -Eq 'rel="?icon' public/index.html || { echo "🔴 홈 <head> 에 rel=icon 이 없다" >&2; exit 1; }

grep 패턴에 따옴표를 선택으로 둔 것은 Hugo의 --minify가 속성 따옴표를 지우기 때문입니다. 압축한 빌드는 rel=icon, 압축하지 않은 빌드는 rel="icon"으로 나왔고 이 패턴은 둘 다 잡았습니다. 패치 전 결과물에 돌리면 두 줄 모두 실패합니다.

파비콘을 다시 손댈 때 볼 순서

작은 나무 상자 안 칸칸이 같은 도장을 크기별로 정리해 두는 책상