Skip to content
Wróć do artykułów
Poradnik5 min czytania

Jak naprawić błąd 404 na /cdn-cgi/l/email-protection w Search Console (zaciemnianie e-maili w Cloudflare)

Dwa błędy w Search Console, których mój kod nie wygenerował: zaciemnianie e-maili w Cloudflare tworzy adres 404, a rekord www wciąż wskazuje parking Namecheap.

CloudflareSEOSearch ConsoleDNSAstro
Nagłówek „Errors your build can’t see” obok karty w stylu Search Console „Why pages aren’t indexed”: przekreślony 404 na /cdn-cgi/l/email-protection, naprawiony znacznikami email_off, i przekreślony 525 na www.pavelsmolin.com, naprawiony przekierowaniem 301 po http.host; na dole build clean, edge 2 errors, fixed 2 / 2

Ta strona jest statyczna. Buduje ją Astro, serwuje Cloudflare Pages, a CI sprawdza każdy pull request. Build nigdy nie wygenerował zepsutego linku. Mimo to Search Console znalazł na niej dwa błędy: Not found (404) i Server error (5xx).

Żaden nie pochodził z repozytorium. Oba wzięły się z konfiguracji Cloudflare, który stoi przed stroną, więc nie złapałby ich ani build, ani testy, ani lokalny podgląd. Poniżej: czym był każdy z nich, jak sprawdzić, czy masz to samo, i jak to naprawić — na wypadek, gdybyś trafił tu, wklejając adres z raportu do wyszukiwarki.

404: /cdn-cgi/l/email-protection

Objaw. Search Console → Strony → Nie znaleziono (404), a na liście dokładnie jeden adres:

https://pavelsmolin.com/cdn-cgi/l/email-protection

Takiej strony u mnie nie ma i nic w kodzie do niej nie linkuje.

Przyczyna. Cloudflare ma domyślnie włączone Email Address Obfuscation (sekcja Scrape Shield). Na brzegu sieci przepisuje każdy adres e-mail w HTML-u, więc zwykły link

<a href="mailto:hello@pavelsmolin.com">hello@pavelsmolin.com</a>

dociera do przeglądarki jako link do /cdn-cgi/l/email-protection#<kod> plus mały skrypt, który odkodowuje adres dla ludzi. Chodzi o boty: zbieracz adresów widzi zakodowany ciąg, a nie adres.

Googlebot też go widzi. Odrzuca fragment po # (fragmenty w ogóle nie trafiają na serwer), odwiedza sam /cdn-cgi/l/email-protection i dostaje 404. Każda strona z adresem e-mail linkuje teraz donikąd. U mnie adres jest w stopce, czyli chodzi o wszystkie strony.

Sprawdzisz to w dziesięć sekund:

curl -s -o /dev/null -w "%{http_code}\n" https://your-site.com/cdn-cgi/l/email-protection
# 404
curl -s https://your-site.com/ | grep -c "email-protection"
# więcej niż zero — Cloudflare przepisuje twoje adresy

Drugie polecenie uruchom na żywej stronie. W lokalnym buildzie podmiany nie zobaczysz, bo powstaje dopiero wtedy, gdy stronę serwuje Cloudflare.

Poprawka. Dwie opcje:

  1. Wyłączyć: panel Cloudflare → twoja domena → Scrape Shield → Email Address Obfuscation → off. Proste i od razu dla wszystkich stron.
  2. Zostawić, ale wyłączyć adresy, które publikujesz świadomie. Tego, co stoi między tymi znacznikami, Cloudflare nie rusza:
<!--email_off--><a href={`mailto:${SITE_EMAIL}`}>{SITE_EMAIL}</a><!--/email_off-->

Na tej stronie przykład powyżej też jest owinięty w te znaczniki — inaczej wpis o błędzie sam stworzyłby jego nową instancję.

Wybrałem drugą opcję dla stopki i strony kontaktowej: poprawka żyje w repozytorium, przechodzi przez review i ma historię jak wszystko inne. Astro zostawia komentarze HTML w zbudowanych stronach, Cloudflare usuwa znaczniki na brzegu sieci i na żywej stronie zostaje zwykły link mailto: bez martwego adresu.

Pułapka to następny adres, który ktoś doda w komponencie albo we wpisie. Zostanie znowu przepisany, a Search Console powie o tym po kilku tygodniach. Dlatego zapisałem tę regułę tam, gdzie czytają ją moje narzędzia, a nie tylko w głowie.

Jak bardzo raport się spóźnia. Googlebot odwiedził martwy adres 7 września, Search Console pokazał go 15-go, a poprawka poszła na produkcję 16-go. Po wdrożeniu kliknij w tym raporcie Sprawdź poprawkę: Google odwiedzi adres ponownie i wyśle maila, kiedy skończy.

Czy 404 na adresie, którego nigdy nie chciałeś publikować, w ogóle szkodzi? Według Google sam 404 nie wpływa na ranking. Ale to link z każdej strony donikąd, bałagan w raporcie, który chcesz mieć pusty, a u mnie — trop do ustawienia, o którym nie wiedziałem.

525: rekord www wskazujący na stronę parkingową

Objaw. Search Console → Błąd serwera (5xx) na www.pavelsmolin.com. W przeglądarce strona błędu Cloudflare: 525: SSL handshake failed. Domena główna działała bez problemu.

Przyczyna. 525 oznacza, że brzeg sieci Cloudflare nie zdołał dokończyć handshake’u TLS z serwerem origin. Pytanie brzmi więc: jaki origin ma www?

Okazało się, że nie ten:

www.pavelsmolin.com   CNAME   parkingpage.namecheap.com   Proxied

To domyślne ustawienie Namecheap dla świeżo kupionej domeny. Przy przenosinach do Cloudflare kreator kopiuje istniejące rekordy, więc ta pozostałość najpewniej przyjechała właśnie tak. Strona działa na Cloudflare Pages, a do projektu Pages była podpięta tylko domena główna. www nadal wskazywało na stronę parkingową Namecheap, przez proxy Cloudflare. Po HTTPS handshake się wysypywał — stąd 525. Zwykłe http://www było gorsze, tylko ciszej: serwowało stronę parkingową Namecheap z kodem 200 pod moją domeną.

dig tego nie pokaże: rekord przez proxy rozwiązuje się na adresy IP Cloudflare, a nie na swój cel. Trzeba zajrzeć do rekordów DNS w panelu.

Poprawka. Przekierować www na brzegu sieci, zanim w ogóle dojdzie do originu. Wtedy stary CNAME przestaje mieć znaczenie — pod warunkiem, że rekord zostaje przez proxy, bo reguła działa tylko na ruchu przechodzącym przez proxy. Rules → Redirect Rules → utwórz:

When:      Custom filter expression
           (http.host eq "www.pavelsmolin.com")
Then:      Dynamic redirect, 301
           concat("https://pavelsmolin.com", http.request.uri.path)
           Preserve query string: on

Dwie rzeczy, na których się potknąłem:

  • Wbudowany szablon „Redirect from WWW to root” dopasowuje tylko https://www.*. Po jego wdrożeniu HTTPS działało, a http://www dalej serwowało parking.
  • Tryb wildcard odrzuca maskę protokołu w rodzaju *://www.example.com/*. Warunek na http.host w custom expression obejmuje oba schematy.

Cloudflare ostrzegł jeszcze, że reguła „może nie działać”, bo DNS „może nie przepuszczać ruchu www przez proxy”. Rekord był przez proxy (pomarańczowa chmurka). Ostrzeżenie się myliło i wdrożenie mimo to było właściwym ruchem.

Weryfikacja przez curl — oba schematy, ze ścieżką i query stringiem:

for u in https://www.your-site.com/about/ "http://www.your-site.com/blog/?a=1"; do
  curl -s -o /dev/null -w "%{http_code} -> %{redirect_url}\n" "$u"
done
# 301 -> https://your-site.com/about/
# 301 -> https://your-site.com/blog/?a=1

Jak długo to wisiało. Pierwszy raz zobaczyłem ten 525 w eksporcie raportu 18 lipca, a naprawiłem 25 września. Diagnoza zajęła minuty. Dwa miesiące zeszły, bo poprawka nie była pull requestem. Błąd z e-mailem naprawiłem tego samego dnia, w którym go znalazłem — jego poprawka żyła w repozytorium.

W międzyczasie licznik 5xx w Search Console sam spadł do zera. To nie była naprawa: Google po prostu przestał odwiedzać ten adres.

Co sprawdziłbym na każdej stronie za Cloudflare

  • Search Console → Strony w nowej usłudze miesiąc po starcie, potem raz w miesiącu. Wszystko pod /cdn-cgi/ należy do Cloudflare, nie do ciebie.
  • Każdy rekord DNS, który przyniósł import. Rekordy parkingowe rejestratora to klasyczna pozostałość.
  • www i domenę główną, po http i po https. Cztery wywołania curl. Każde powinno kończyć się kodem 200 na jednym kanonicznym hoście.
  • Wszystko, co Cloudflare przepisuje na brzegu sieci: zaciemnianie e-maili, Rocket Loader, wstrzykiwane skrypty. Google indeksuje żywy HTML, a nie twój build.

Wniosek jest niewielki, ale ciągle wraca: czysty build dowodzi, że w porządku jest repozytorium, i nic nie mówi o warstwie przed nim. Jeśli twoja strona stoi za Cloudflare, a Search Console pokazuje błędy, których nie możesz znaleźć w kodzie — napisz do mnie. Zwykle to jeden z tych dwóch.

Pavel Smolin · 28 października 2026

Powiązane artykuły

Poradnik4 min czytania

Jak dodać serwer MCP Supabase do Claude Code

Jedna komenda łączy Supabase z Claude Code przez hostowany serwer MCP: OAuth albo personal access token, project_ref, tryb tylko do odczytu i które narzędzia dodać do allowlisty.

Poradnik3 min czytania

Jak dodać serwer MCP RevenueCat do Claude Code

RevenueCat łączy się z Claude Code dwiema komendami: oficjalny plugin albo hostowany serwer MCP. OAuth czy klucz API, jak sprawdzić połączenie i co dodać do allowlisty.