Ви випустили нову маркетингову сторінку, хтось вставив посилання в Slack, і тепер кожен клік потрапляє в глухий кут. Не елегантний глухий кут. Стандартний 404 від вебсерверу з холодним «Not Found», як зачинені двері без таблички і ручки.
Це дрібниці, що коштують реальних грошей: користувачі йдуть, звернення в підтримку накопичуються, пошукові системи плутаються, а ваш відповідальний інженер отримує сповіщення, бо спайк 404 виглядає як інцидент. Хороша сторінка 404 — це не «мило». Це запобігання інцидентам, загорнуте в UX.
Для чого насправді потрібна сторінка 404 (і для чого ні)
Сторінка 404 — це одночасно підтримка користувачів, навігація і телеметрія. Ставтеся до неї як до операційної поверхні, а не декоративного арту помилок.
Коли хтось потрапляє на відсутній URL, він повідомляє вам одне з чотирьох:
- Він перейшов за битим посиланням (внутрішнім, зовнішнім або через застарілий кеш).
- Він щось неправильно ввів (людська помилка, автозаповнення або «я ж пам’ятаю, що тут було»).
- Бот робить розвідку (звичайні краулери, сканери безпеки, випадкові запити).
- Маршрутизація або деплой у вас неправильні (неправильні rewrite-правила, відсутні ресурси, частковий rollout, дивна поведінка CDN).
Завдання 404 — швидко відсортувати ці випадки: якщо можливо, відновити користувача та дати вам достатньо даних, щоб виправити корінь проблеми. Чого не слід робити — прикидатися, що все добре. Повернення 200 з повідомленням про помилку — це SEO- та кеш-фоллгаб, і воно ускладнює розслідування, бо «успіх» метрик ховає реальний збій.
Є також соціальний контракт. Користувач, що потрапив на 404, відчуває легкий дискомфорт, навіть якщо це ваша вина. Не підсилюйте це пасивно-агресивним тоном. Будьте прямими, корисними і рухайте їх уперед.
Факти та історія, що важливі в 2025
Це не тривія заради тривії. Кожен пункт пояснює, чому певні вибори стосовно 404 досі мають наслідки.
- HTTP 404 визначено як «Not Found», що означає, що сервер не має поточної репрезентації ресурсу. Слово «поточна» важливе: воно не стверджує, що ресурс ніколи не існував, лише що зараз його немає.
- 410 Gone — інший випадок. 410 є явною заявою, що ресурс навмисно і постійно видалено. Пошукові системи зазвичай швидше виключають 410 URL, ніж 404.
- Пошукові системи виокремили термін «soft 404» для сторінок, які виглядають як помилки, але повертають 200 OK або редиректять усі запити на головну. Це шкодить індексації та довірі.
- Ранні вебсервери відправляли голі сторінки помилок, бо пропускна здатність і CPU були дорогими, а динамічні шаблони рідше використовувались. Ця спадщина досі визначає дефолти: багато стеків надсилають мінімальний HTML для 404, якщо ви не перевизначите.
- CDN популяризували обробку помилок на краю. 404 може кешуватися на edge так само, як 200, і це може бути ваш найкращий друг (швидкість) або найбільший ворог (застарілі «відсутні» сторінки після деплою).
- Браузери й проксі трактують 404 інакше, ніж 200. Наприклад, кеші можуть зберігати 404 за іншими евристиками, а клієнтський код часто дивиться на статус-коди, щоб розгалужувати логіку.
- Сканери безпеки люблять поверхні 404. Багато експлойтів починаються з розвідки: запити на стандартні адмін-шляхи, старі плагіни або неправильні бекапи. Хедери і час відповіді 404 можуть пролити світло на стек, якщо ви неакуратно їх показуєте.
- SPA ускладнили маршрутизацію 404. Клієнтські роутери часто хочуть «віддавати index.html для невідомих шляхів», що правильно для app-маршрутів, але неправильно для реально відсутнього контенту. Різниця важлива для SEO і зрозумілості користувача.
- Раніше биті посилання були «чужою проблемою». Сьогодні аналітика та інструменти Search Console роблять це вимірюваним, тож ігнорування 404 — це свідомий вибір, зазвичай поганий.
Принципи дизайну: зробіть 404 корисною
1) Підтвердіть, що сталося, без драматизму
Скажіть правду простими словами: «Ми не можемо знайти цю сторінку». Потім запропонуйте кілька дій. Не звинувачуйте користувача. Не натякайте, що сайт зламався, якщо це не так. 404 часто означає одну відсутню URL, а не загальний збій.
2) Дайте два–три якісні виходи
Хороша сторінка 404 навмисно лаконічна. Ви не відтворюєте навігацію; ви пропонуєте аварійні виходи:
- Головна (так, але не покладайтесь лише на неї).
- Пошук (найкращий універсальний інструмент відновлення).
- Топ-завдання для вашого продукту (ціни, документація, статус, контакт, вхід — обирайте те, що дійсно потрібно користувачам).
Тримайтеся в межах 5–8 посилань. Занадто багато посилань виглядає як збайдуженість, і користувачі все одно йдуть.
3) Зберігайте контекст, коли це можливо
Якщо ви знаєте, звідки прийшов користувач, використайте це. «Повернутися назад» — це функція браузера, і користувачі її знають. Дайте реальне посилання: «Повернутися на попередню сторінку» (на основі referrer), або покажіть підказки «Можливо, ви мали на увазі…», згенеровані з відсутнього шляху.
Одна проста хитрість, яка працює: розпарсити сегменти шляху і запропонувати ширший батьківський шлях, якщо він існує (наприклад, /docs/storage/… → /docs/storage/).
4) Не витягайте внутрішні дані
Сторінку 404 бачать усі, включно з ботами, що збирають ваші помилки. Уникайте:
- Рядків з версіями фреймворків у хедерах або HTML.
- Трасування стеку, ідентифікаторів відладки, що прив’язуються до внутрішніх систем, або сирих повідомлень винятків.
- Відображення невідомого вмісту URL у сторінці без екранування.
5) Робіть сторінку дешевою у видачі
404 виникають у сплесках. Коли щось ламається — популярний блоговий лінк, перейменування продукту, деплой, який видалив endpoint — частота 404 може зрости у 10–100×. Якщо ваша 404 залежить від повільних бекенд-запитів або важких клієнтських бандлів, ви перетворюєте помилку контенту на інцидент доступності.
6) Інструментуйте її як продукційну кінцеву точку
Вам треба знати:
- Які відсутні URL найгарячіші.
- Referrer’и, що генерують битий трафік.
- User agent’и, що вказують на сканери або людей.
- Чи корелюють 404 зі деплоєм, змінами CDN або зсувами DNS.
Текст і гумор: легкий підморг, а не стендап
Пишіть текст так, як писали б апдейт інциденту: спокійно, чітко і орієнтовано на наступні кроки.
Робіть: «Ця сторінка тут відсутня. Спробуйте пошук або перейдіть до цін.»
Не робіть: «Ой-ой! Щось пішло не так!!!» (Нічого не пішло — просто лінк відсутній.)
Гумор допустимий, але легкий і опціональний — як приправа. Якщо користувач застряг, жарти виглядають, ніби ви смієтесь над ним. Якщо користувач може швидко відновитися, невеликий жарт доречний.
Жарт №1: Сторінка, яку ви просили, пішла на перерву на каву і не залишила адреси пересилання.
Зверніть увагу, що цей жарт не робить: не зневажає користувача, не згадує «помилки сервера» і не натякає на нестабільність сайту. Це маленький людський момент, потім — назад до справи.
Жарт №2: Ми шукали всюди — навіть під кешем — але цей URL усе ще не реальний.
Достатньо двох жартів. Якщо вам потрібно більше гумору, вам насправді потрібна краща інформаційна архітектура, редиректи та гігієна посилань.
Поле пошуку: зробіть його швидким, безпечним і корисним
Поле пошуку — найпотужніша функція на сторінці 404. Воно перетворює «глухий кут» на «продовжити завдання». Але тільки якщо працює швидко і повертає релевантні результати.
Поведінкові вибори пошуку, що мають значення
- Автофокус на полі для десктопів. На мобайлі будьте обережні: автофокус може викликати клавіатуру і дратувати. Зробіть це умовним.
- Підставляйте пропозицію з відсутнього шляху, як підказку, а не як примусову пошукову фразу. Часто люди хочуть близький термін, а не «docs-v2-final-final».
- Приймайте прості запити. Не вимагайте складного синтаксису. Це інструмент відновлення, не консоль просунутих користувачів.
- Повертайте результати швидко. Якщо ваш бекенд пошуку повільний, деградуйте граційно: покажіть кураторські посилання і спосіб перегляду категорій.
Контроль безпеки та протиабузні механізми
Ендпоїнти пошуку приваблюють скреперів. Ваша 404 може стати підсилювачем пошукового трафіку, якщо боти надсилають випадкові URL і ви відповідаєте важкими пошуковими запитами.
Механізми, що не калічать UX:
- Не запускайте пошук автоматично тільки тому, що стався 404. Чекайте на дію користувача (submit) або робіть дуже дешевий список пропозицій з локального індексу.
- Рейт-лімітуйте пошукові запити по IP і/або сесії. Тримайте саму сторінку 404 відокремленою від дорогої частини.
- Встановлюйте таймаут для пошукових викликів на суворий ліміт, а потім переключайтесь на кураторські посилання. Повільний пошук гірший за відсутність пошуку.
- Екрануйте введення і уникайте відображення сирих рядків запиту в HTML. Це стандартна гігієна проти XSS, а 404 часто ціль при таких атаках, бо відображає запитаний шлях.
Операційна реальність: пошук — це залежність
Якщо сторінка 404 викликає бекенд пошуку, ви зробили «відсутній лінк» залежним від вашої найскладнішої системи. Правило: сторінка 404 має повністю відрендеритися без викликів upstream. Пошук може бути посиланням на сторінку пошуку або вбудованою формою, що відправляє на окремий ендпоїнт. Сам 404-відповідь має залишатися дешевоъ.
Інженерія надійності має тут чіткий принцип. Як переказано з ідеї Джона Галла: «Складні системи, що працюють, зазвичай еволюціонували з простіших систем, що працювали». Ваша 404 має бути однією з найпростішіх сторінок, які ви подаєте.
Корисні посилання, що не нагадують карту сайту
Сторінка 404 з 40 посиланнями — це просто інший вид «не знайдено». Куруйте.
Як вибирати правильні посилання
Обирайте посилання за наміром, а не за організаційною структурою. В корпоративних сайтах оргструктура часто просочується в навігацію. Опирайтеся цьому. Користувачам байдуже, який віце-президент відповідає за «Рішення». Їм важливо зробити дію.
Хороші дефолти для багатьох продуктів:
- Головна
- Пошук (або посилання на пошук)
- Ціни (або Плани)
- Документація (або Центр допомоги)
- Статус (якщо є; якщо ні — не фальшувати)
- Зв’язок з підтримкою
- Увійти (якщо застосовно)
Поради з урахуванням контексту
Контекстні підказки краще за загальні. Приклади, що працюють:
- Якщо шлях починається з
/docs/, запропонуйте «Домашню сторінку документації» і «API reference». - Якщо шлях починається з
/blog/, запропонуйте «Останні пости» і «Тематики». - Якщо шлях виглядає як ресурс (
.js,.css,.png), покажіть коротке повідомлення для розробників: «Схоже, це відсутній статичний файл. Якщо ви деплоїте, перевірте pipeline активів і кеш CDN.»
Посилання для повідомлення про проблему (без створення лавини звернень)
Опція «Повідомити про битий лінк» може бути цінною, але лише при розумній реалізації:
- Попередньо заповнюйте відсутній URL і referrer.
- Вимагайте мінімальних зусиль (одне натискання, щоб відкрити форму).
- Не вимагайте входу, якщо ваш продукт не ексклюзивно аутентифікований.
- Маршрутуйте звернення в триаж (а не безпосередньо на інженерні сторінки). Інакше ви звикнете людей використовувати це як загальний канал скарг.
HTTP і SEO: уникайте пасток «soft 404»
Ось моя принципова порада: повертайте 404 для контенту, якого не існує. Не редиректьте все на головну. Не повертайте 200 з дружнім повідомленням. Саме так індекс заповнюється сміттям, а моніторинг — неправдивими даними.
Вибір статус-кодів
- 404 Not Found: дефолт для відсутніх сторінок або ресурсів.
- 410 Gone: використовуйте для навмисно і постійно видаленого контенту.
- 301 Moved Permanently: коли є чітка заміна URL. Не 301 на «майже схоже».
- 302/307: для тимчасових переміщень під час міграцій або експериментів.
Канонічність та індексація
Сторінка 404 не повинна індексуватися як контент. Зазвичай ви робите таке:
- Повертаєте правдивий статус 404.
- Додаєте мета-тег
noindex(страховка; статус уже повідомляє більшості краулерів, що робити). - Уникаєте canonical-тегів, що вказують на реальні сторінки, якщо ви не робите це свідомо.
Чому «редирект на головну» — погана звичка
Це здається корисним. Насправді ні. Воно ховає биті посилання, плутає аналітику і вчить краулери, що ваш сайт не поважає значення URL. Користувачі теж ненавидять це: вони клікнули на конкретну сторінку і потрапили в лобі без вказівок.
SPA: розділяйте «невідомий маршрут» від «відсутнього контенту»
SPA часто віддають index.html для будь-якого шляху, щоб клієнтський роутер зміг відрендерити відповідний вигляд. Це нормально для валідних app-маршрутів. Але коли маршрут справді не існує, ви все одно хочете 404 — а не 200 з компонентом «page not found».
Практичний підхід: тримайте на сервері allowlist для SPA-шляхів або повертайте 404 на рівні API для невідомого контенту і робіть так, щоб сервер повертав 404 для невідомих asset-шляхів.
Логування, моніторинг і алерти: 404 як сигнали
404 не завжди «помилки» в операційному сенсі. Боти роблять розвідку. Старі посилання існують. Але спайки і шаблони — дієві, і якщо ви їх ігноруєте, потім доведеться робити археологію подій.
Що логувати для 404
- Запитаний шлях і рядок запиту (з правилами приватності).
- Referrer.
- User agent (або його хеш/парсована класифікація).
- Host header (важливо для мульті-тенантних сайтів).
- Час відповіді і upstream time (для хорошої 404 upstream має бути майже нульовим).
- Статус кешу (HIT/MISS/BYPASS) якщо ви за CDN або реверс-проксі.
На що ставити алерти
Алертуйте про зміну темпу, а не про абсолютні значення. Сайт з великою кількістю довгих контентів завжди матиме деякі 404.
- Спайк 404 відносно базової лінії.
- Окремий 404 URL раптом «гарячий» (часто вказує на битий внутрішній лінк або помилку в маркетинговій кампанії).
- 404 для статичних ресурсів (може вказувати на битий деплой, відсутні артефакти або проблеми з CDN).
- Високий рівень 404 + велика латентність (ваш 404 обробник робить занадто багато роботи).
Приватність і відповідність
Не логируйте персональні дані без потреби. Рядки запитів часто містять email’и, токени або пошукові терміни. Ви можете бути корисними, дотримуючись обережності:
- Видаляйте або хешуйте відомі чутливі параметри.
- Тримайте короткий строк зберігання сирих логів; агреговані метрики — довше.
- Класифікуйте user agent замість зберігання повних рядків, якщо можливо.
Продуктивність і надійність: 404 на гарячому шляху
Більшість команд думають про продуктивність для головної сторінки і ключових потоків продукту. Тим часом 404 тихо стає вектором витрат, бо його легко викликати і часто погано кешувати.
Тримайте вагу відповіді малою
Сторінка 404 має бути переважно HTML з дрібним CSS. Якщо ви віддаєте величезний JS-бандл, щоб повідомити користувачу «не знайдено», ви отримаєте рахунок, якого заслуговуєте.
Кешуйте стратегічно
Кешування 404 корисне, але має нюанси:
- Кешуйте 404 для очевидних бот-проб (наприклад, стандартні шляхи експлойтів) коротким TTL, на краю, якщо можливо.
- Будьте обережні з кешуванням 404 для контенту, що може з’явитися. Якщо ви закешуєте 404 для URL, який з’явиться після наступного деплою, ви створюєте інцидент «працює на origin, але не на edge».
- Використовуйте різні TTL по префіксу шляху. 404 для статичних ресурсів можна кешувати довше; для динамічних контент-путів — коротше.
Зробіть її стійкою до відмов бекенду
Один з моїх улюблених тихих виграшів — віддавати 404 прямо з реверс-проксі, без залежності від аплікації. Коли аплікація впала, проксі все ще може правильно відповідати на відсутні шляхи і не блокувати upstream-черги.
Швидкий playbook для діагностики
Це робочий процес «в мене 15 хвилин і нетерплячий стейкхолдер». Мета — визначити, чи вузьке місце у контенті, маршрутизації, кешуванні чи деплої.
Перше: підтвердіть статуси і охоплення
- Це справжній 404 від origin, або 404 від CDN/WAF, або 200 з «not found» контентом?
- Це один URL чи весь префікс?
- Це лише один регіон/POP, чи скрізь?
Друге: знайдіть referrer і джерело істини
- Внутрішнє посилання? Виправте негайно і задеплойте.
- Зовнішнє посилання? Додайте редирект, якщо воно популярне і призначення очевидне.
- Шум від ботів? Рейт-лімітуйте або кешуйте; не панікуйте.
Третє: перевірте зміни деплою і маршрутизації
- Чи змінилося правило rewrite?
- Чи правило SPA fallback випадково поглинуло реальні 404?
- Чи будувались активи, але не публікувались (несумісні хеші, відсутні артефакти)?
Четверте: перевірте поведінку кешу
- Чи CDN кешує 404 занадто агресивно?
- Чи origin відправляє заголовки кешування, яких ви не очікували?
- Чи є застаріла конфігурація edge?
П’яте: валідируйте саму сторінку 404
- Чи обробник 404 повільний або викликає upstream-сервіси?
- Чи він генерує помилки (500) під навантаженням?
- Чи завантажує важкий JS/CSS з відсутніх URL (404 всередині 404)?
Практичні завдання: команди, вивід і рішення
Ці завдання призначені для реальної продакшн-діагностики. Кожне містить команду, приклад виводу, що це означає, і яке рішення ухвалити далі.
Завдання 1: Перевірити, що статус-код справжній 404 (не soft 404)
cr0x@server:~$ curl -s -D- -o /dev/null https://www.example.com/definitely-missing-page
HTTP/2 404
date: Mon, 29 Dec 2025 10:15:21 GMT
content-type: text/html; charset=utf-8
cache-control: max-age=60
Що це означає: Сервер повертає реальний 404. Добрий початок. Cache-Control вказує, що це може кешуватися 60 секунд.
Рішення: Якщо користувачі кажуть «сторінка є, але я бачу 404», підозрюйте кешування або rollout. Якщо вона справді відсутня — переходьте до аналізу referrer.
Завдання 2: Виявити soft 404 (200 з «not found» контентом)
cr0x@server:~$ curl -s -D- https://www.example.com/definitely-missing-page | head -n 12
HTTP/2 200
date: Mon, 29 Dec 2025 10:16:02 GMT
content-type: text/html; charset=utf-8
<!doctype html>
<html>
<title>Page not found</title>
Що це означає: Це soft 404. Ваш моніторинг, кешування і SEO постраждають.
Рішення: Виправте маршрутизацію, щоб відсутній контент повертав 404. Для SPA — впровадьте allowlist на сервері або правильну обробку статусів.
Завдання 3: Перевірити, чи CDN повертає 404
cr0x@server:~$ curl -s -D- -o /dev/null https://www.example.com/definitely-missing-page | egrep -i 'server:|via:|x-cache:|cf-cache-status:|x-served-by:'
server: cloudflare
cf-cache-status: HIT
Що це означає: Відповідь від CDN і закешована (HIT). Origin міг не брати участі.
Рішення: Якщо сторінка нещодавно почала існувати — очистіть кеш або зменшіть TTL для 404 на цьому шляху. Якщо вона справді відсутня — розгляньте довше кешування для ботових шляхів.
Завдання 4: Підтвердити поведінку origin, обминаючи CDN (де можливо)
cr0x@server:~$ curl -s -D- -o /dev/null --resolve www.example.com:443:203.0.113.10 https://www.example.com/definitely-missing-page
HTTP/2 404
date: Mon, 29 Dec 2025 10:18:12 GMT
server: nginx
Що це означає: Прямий доступ до origin також повертає 404, тож CDN не вигадує помилку.
Рішення: Розглядайте це як відсутній контент або проблему маршрутизації origin. Перейдіть до логів, щоб знайти referrer’и та патерни.
Завдання 5: Знайти топ 404 шляхів у логах NGINX
cr0x@server:~$ awk '$9==404 {print $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head
842 /wp-login.php
311 /docs/storage/zfs-tuning
207 /assets/app.8f3c1d.js
98 /favicon.ico
Що це означає: Є і бот-проби (/wp-login.php), і ймовірно реальне биття лінку (/docs/storage/zfs-tuning) та відсутній ресурс-актив.
Рішення: Бот-проба: короткий кеш і/або правило WAF. Док-посилання: додайте редирект або виправте внутрішні лінки. Відсутній актив: негайно перевіряйте деплой/CDN.
Завдання 6: З’ясувати, хто посилається на відсутній URL (аналіз referrer)
cr0x@server:~$ awk '$9==404 {print $11}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head
126 "https://www.example.com/docs/storage/"
88 "https://www.example.com/blog/introducing-zfs"
41 "-"
Що це означає: Сторінка документації і блог посилаються на відсутні цілі. «-» означає відсутній referrer (введено вручну/закладка/бот).
Рішення: Виправте сторінки-джерела першими. Редиректи допомагають, але виправлення внутрішніх посилань запобігає повторним 404.
Завдання 7: Підтвердити, чи існує відсутній актив на диску (перевірка збірки статичних файлів)
cr0x@server:~$ ls -lh /var/www/html/assets/ | head
total 12M
-rw-r--r-- 1 www-data www-data 92K Dec 29 09:57 app.91a2ce.js
-rw-r--r-- 1 www-data www-data 31K Dec 29 09:57 app.91a2ce.css
Що це означає: Актив, згаданий у логах (app.8f3c1d.js), відсутній; існує інший хеш. Ймовірно, HTML посилається на застарілу збірку або стався частковий деплой.
Рішення: Перевірте артефакти деплою і забезпечте атомарність публікації HTML та активів. Якщо використовуєте CDN, очищуйте старий HTML або корегуйте кешування, щоб уникнути несумісних бандлів.
Завдання 8: Перевірити конфіг NGINX на обробку 404 і SPA fallback
cr0x@server:~$ sudo nginx -T 2>/dev/null | egrep -n 'error_page|try_files|location /' | head -n 20
45: error_page 404 /404.html;
78: location / {
79: try_files $uri $uri/ /index.html;
80: }
Що це означає: Сервер використовує try_files з fallback на /index.html. Це нормально для SPA-маршрутів, але може створити soft 404, якщо index.html повертає 200 для відсутніх шляхів.
Рішення: Переконайтеся, що SPA-роутер повертає правильний 404 для невідомих клієнтських маршрутів, або реалізуйте серверну відмінність між відомими SPA-шляхами і невідомими.
Завдання 9: Перевірити, що сторінка 404 легка (TTFB і розмір)
cr0x@server:~$ curl -s -o /dev/null -w "status=%{http_code} ttfb=%{time_starttransfer} size=%{size_download}\n" https://www.example.com/definitely-missing-page
status=404 ttfb=0.038241 size=6142
Що це означає: Швидкий TTFB і невеликий payload. Саме цього ви хочете.
Рішення: Якщо TTFB високий, шлях 404 робить бекенд-роботу. Виправте, віддаючи статичну 404 на edge/proxy.
Завдання 10: Перевірити заголовки кешування для 404
cr0x@server:~$ curl -s -D- -o /dev/null https://www.example.com/definitely-missing-page | egrep -i 'cache-control|expires|age'
cache-control: public, max-age=3600
age: 2540
Що це означає: 404 кешується годину і вже знаходиться в кеші 42 хвилини. Це може бути правильним для бот-проб, але небезпечним для нещодавно опублікованого контенту.
Рішення: Зменшіть TTL для шляхів, схожих на контент; тримайте довший TTL для явного «мусору». Розділіть правила по location-блоках або правилах CDN.
Завдання 11: Перевірити, чи існують редиректи для відомих застарілих шляхів
cr0x@server:~$ curl -s -D- -o /dev/null https://www.example.com/docs/storage/zfs-tuning | head -n 8
HTTP/2 404
date: Mon, 29 Dec 2025 10:24:19 GMT
Що це означає: Редиректу немає. Якщо це поширена помилка (завдання 5), ви втрачаєте користувачів.
Рішення: Додайте 301 до найкращої заміни або відновіть сторінку, якщо її випадково видалили. Якщо її навмисно видалено — розгляньте 410.
Завдання 12: Визначити, чи корелюють 404 з часом деплою
cr0x@server:~$ journalctl -u nginx --since "2025-12-29 09:30" --until "2025-12-29 10:30" | egrep -i 'reload|signal|start'
Dec 29 09:58:01 web-1 nginx[1321]: signal process started
Dec 29 09:58:02 web-1 nginx[1321]: signal process started
Що це означає: Перезавантаження NGINX відбулося близько часу зміни активів. Разом з відсутніми хешами активів це вказує на проблему деплою.
Рішення: Перевірте пайплайн деплою на атомарність; переконайтеся, що HTML посилається на правильний хеш активу і що кеши очищуються скоординовано.
Завдання 13: Виявити 404-шторм від одного UA бота
cr0x@server:~$ awk '$9==404 {print $12,$7}' /var/log/nginx/access.log | head -n 3
"Mozilla/5.0" /wp-login.php
"SomeScanner/1.2" /admin.php
"SomeScanner/1.2" /.git/config
Що це означає: Сканер перевіряє стандартні шляхи. Такі запити повинні бути дешевими у видачі і, бажано, блокуватися або уповільнюватися на краю.
Рішення: Додайте WAF-правила або rate limiting у NGINX для зловмисних патернів. Кешуйте такі 404 довше з мінімальним тілом, щоб зберегти ресурси origin.
Завдання 14: Переконатися, що сама 404 не викликає додаткових 404 (відсутні CSS/JS)
cr0x@server:~$ curl -s https://www.example.com/404.html | egrep -o 'href="[^"]+|src="[^"]+' | head
href="/assets/app.8f3c1d.css
src="/assets/app.8f3c1d.js
Що це означає: Ваша 404 залежить від активів, які можуть бути відсутні (як бачилося раніше). Це створює другий режим збою: «404 сторінка відображається некоректно», і породжує ще більше 404 у логах.
Рішення: Інлайньте мінімальний CSS для 404 або посилайтеся на стабільні, версіоновані активи, гарантовано наявні. Тримайте її незалежною від основного бандла.
Три корпоративні міні-історії (анонімізовано, болісно правдоподібно)
Міні-історія 1: Інцидент через хибне припущення
Компанія була в процесі ребрендингу, тож URL змінювалися. Продуктовий менеджер попросив «жодних битих лінків», і хтось переклав це як «редиректити всі невідомі шляхи на головну». Це звучало клієнтськи і зробило графік 404 тихим. Усі сприйняли тишу як успіх.
Два тижні потому конверсії з платного пошуку впали. Не обвал — але просіли. Маркетинг звинувачував таргетинг. Веб-команда списувала все на трекінг. Аналітика показувала здоровий трафік і підозріло низький рівень 404, що виглядало як доказ відсутності «битих лінків».
Справжня проблема: користувачі потрапляли на глибокі сторінки з реклами і старих матеріалів, їх 302 редиректило на головну, і вони відразу йшли. Сесії виглядали «успішними» в базових дашбордах, бо головна була 200. Фандел розвалився, бо зник намір сторінки приземлення.
Коли SRE на виклику нарешті подивився сирі логи, все стало очевидно: невеликий набір старих висококонверсійних URL редиректилося на «/» з високим обсягом. Виправлення було нудним: реалізувати конкретні 301 редиректи до нових сторінок, відновити справжні 404 для невідомих URL і додати моніторинг аномалій «редирект на головну».
Хибне припущення було в тому, що «користувачі ненавидять 404, тож усуньмо їх». Користувачі ненавидять глухі кути. Правдива 404 з полем пошуку краща за брехливий редирект на головну.
Міні-історія 2: Оптимізація, що відсічилася назад
Команда вирішила знизити навантаження на origin. Вони почали агресивно кешувати 404 на краю: Cache-Control: public, max-age=86400 для всього, що повертало 404. Це відразу спрацювало для бот-шуму і випадкових проб. Обсяг запитів до origin впав. Хтось оголосив перемогу.
Потім партнер опублікував високонавантажуване посилання на сторінку, яка ще не існувала, бо реліз відсунувся на день. Перший сплеск трафіку повернув 404, CDN закешував його на день. Коли сторінка стала онлайн через кілька годин, користувачі все ще отримували 404 з краю.
Інцидент був болючим тому, що виглядав як «сторінка задеплоєна, але все ще відсутня». Тести origin проходили. Лише деякі регіони були уражені. Була ініційована очистка кешів, але реплікація не була миттєвою і не всі кеші очистилися однаково.
Висновок не був «ніколи не кешувати 404». Він полягав у «кешувати 404 з наміром». Вони ввели TTL по префіксах: короткі TTL для шляхів, що можуть з’явитися, довгі TTL для очевидних проб ботів, і миттєве обхідне правило для критичних префіксів під час релізів.
Оптимізація — не синонім «встановити довгий TTL». Оптимізація — це вибір того, у чому ви можете дозволити собі помилитися.
Міні-історія 3: Нудна, але правильна практика, що врятувала ситуацію
Інша компанія мала правило, яке звучало неефектно: кожен 404 повинен містити внутрішній request ID, а топ-20 404 шляхів переглядалися щотижня. Не «коли буде час». Щотижня. Розгляд чергувався між веб-командою і підтримкою.
Одного понеділка звіт показав новий гарячий 404: шлях у розділі білінгу. Referrer був внутрішній: посилання в шаблоні листа для онбордингу. Ніхто не чіпав білінг-додаток. Шаблон листа керувався маркетингом.
Оскільки 404 сторінка містила request ID і логи були структуровані, вони відстежили проблему за кілька хвилин. URL пропускав дефіс — проста людська помилка. Виправлення теж було нудним: оновити шаблон листа і додати редирект зі старого URL на правильний для підстраховки.
Найкраща частина: це ніколи не стало «збоєм сайту». Це залишилося невеликою операційною подряпиною, яку виправили до того, як вона почала кровоточити. Немає звинувачень. Ніякої драми. Просто невелика щотижнева звичка, що окупилася.
Нудні процеси недооцінені. Трюк у тому, щоб вибрати саме ті нудні процеси, що реально пов’язані з болем користувачів.
Типові помилки: симптом → корінь → виправлення
1) Симптом: «Наша сторінка 404 відображається у результатах Google»
Корінь: Soft 404 (статус 200), або неправильна канонічна/noindex політика, або CDN переписує статуси.
Виправлення: Поверніть справжній 404 для відсутніх сторінок. Додайте мета noindex у шаблон 404. Перевірте через curl -D-, що статус 404 проходить до краю (включно з CDN).
2) Симптом: «Користувачі бачать головну сторінку, коли клікають на старі лінки»
Корінь: Правило catch-all редиректів для невідомих шляхів.
Виправлення: Видаліть catch-all редиректи. Додайте цілеспрямовані 301 для відомих застарілих URL і зберігайте справжні 404 для невідомих.
3) Симптом: «Спайк 404 після деплою, здебільшого активи»
Корінь: Неатомарний деплой HTML + хешованих активів; застарілий HTML кешується довше за активи; неправильний порядок purge.
Виправлення: Деплойте активи першими, потім HTML, або публікуйте у версіоновані директорії і переключайте вказівник атомарно. Вирівняйте кешування: короткий TTL для HTML, довгий для незмінних хешованих активів.
4) Симптом: «Сторінка 404 повільна і таймаутиться під навантаженням»
Корінь: Обробник 404 викликає сервісні залежності (пошук, персоналізація, експерименти) або рендериться важкими серверними шаблонами.
Виправлення: Віддавайте статичну 404 на проксі/edge. Тримайте її незалежною від upstream. Обмежуйте час викликів опціональних сервісів і в разі проблем показуйте статичну версію.
5) Симптом: «Не можемо відтворити 404; лише користувачі в одному регіоні бачать його»
Корінь: Кешування 404 на CDN, непослідовні очистки або розділені деплои.
Виправлення: Перевірте заголовки кешування і статус кешування. Обійдіть CDN для тесту origin. Очистіть конкретні URL, потім налаштуйте TTL по шляху.
6) Симптом: «Підтримку засипають повідомленнями про биті лінки»
Корінь: Кнопка звіту про лінк без фільтрів; боти тригерять її; користувачі використовують її як загальний канал.
Виправлення: Додайте базові механізми проти зловживань (rate limit, CAPTCHA лише за потреби), включіть структуровані поля і маршрутуйте в чергу триажу з чіткими категоріями.
7) Симптом: «Команда безпеки скаржиться, що 404 витікає деталі стеку»
Корінь: Рядки сервера за замовчуванням, заголовки фреймворку, debug-вивід або відображене введення.
Виправлення: Видаліть/перезапишіть серверні токени, вимкніть debug, екрануйте всі відображені рядки і переконайтеся, що шаблони помилок не містять деталей середовища.
8) Симптом: «Моніторинг не показує проблему, але користувачі скаржаться»
Корінь: Soft 404 рахується як успіх, або дашборди відстежують лише 5xx, або редиректи ховають помилки.
Виправлення: Відслідковуйте 404 і 3xx окремо. Алертуйте на зміни. Логуйте referrer’и. Моніторьте топ відсутніх шляхів.
Чеклісти / покроковий план
Чекліст A: Зробити 404, що допомагає користувачам відновитися
- Напишіть зрозумілий текст: «Ми не можемо знайти цю сторінку.» Ніяких звинувачень і паніки.
- Додайте поле пошуку, що відправляє на виділений ендпоїнт пошуку (не викликайте пошук при рендері).
- Кураторіть 5–8 посилань на топ-завдання. Тримайте їх лаконічними.
- Запропонуйте контекст: покажіть запитаний шлях, безпечно екранований, і «повернутися» якщо є referrer.
- Додайте опцію повідомити лише якщо ви в змозі триажити. Попередньо заповніть URL і referrer.
- Зробіть її доступною: правильні заголовки, управління фокусом і читабельний контраст.
Чекліст B: Зробити все правильно для SEO і кешування
- Повертайте HTTP 404 для відсутніх ресурсів. Валідуйте на краю.
- Використовуйте 410 вибірково для навмисно видалених сторінок.
- Додайте noindex у шаблон 404.
- Не редиректьте невідомі URL на головну. Використовуйте цільові редиректи лише.
- Встановіть розумні заголовки кешування: короткий TTL для шляхів схожих на контент, довший TTL для очевидних бот-проб.
Чекліст C: Інструментація і операції
- Логуйте 404 структуровано: шлях, статус, referrer, клас UA, request ID, статус кешу.
- Створіть звіт топ-404 (щодня або щотижня) і призначте відповідальних.
- Алертуйте на спайки, а не на саме існування. 404 — нормальні; різкі зміни — ні.
- Відслідковуйте 404 активів окремо від сторінок.
- Запускайте перевірку внутрішніх битих лінків як частину CI для документації/контенту.
Чекліст D: Безпека при міграціях і редизайні
- Зробіть інвентар високотрафікових URL перед зміною інформаційної архітектури.
- Плануйте редиректи для очевидних замін; уникайте «майже подібних» редиректів.
- Тримайте старі URL живими деякий час з 301, особливо для документації та постів блогу.
- Повторно тестуйте після змін CDN: статуси, кешування і поведінку purge.
FAQ
Чи має сторінка 404 повертати 404 чи 200?
Повертайте 404. 200 з «not found» — це soft 404, що ламає SEO-сигнали, точність аналітики і оперативну видимість.
Коли слід використовувати 410 Gone замість 404?
Використовуйте 410, коли ви впевнені, що контент навмисне видалено і не повернеться. Це сильніший сигнал для краулерів і зменшує повторний краул мертвих URL.
Чи нормально редиректити відсутні сторінки на головну?
Ні, не як універсальне правило. Це ховає биті лінки і шкодить наміру користувача. Використовуйте цілеспрямовані редиректи лише коли є реальна заміна.
Чи має сторінка 404 містити повне навігаційне меню сайту?
Зазвичай ні. Дайте невеликий набір високовартісних посилань. Повна навігація заохочує «блукати, поки не здадуться» і збільшує вагу сторінки.
Чи потрібен нам поле пошуку на 404?
Якщо у вас більше кількох сторінок — так. Це найшвидший інструмент відновлення. Але не робіть рендер 404 залежним від виклику пошукового бекенду.
Як запобігти ботам, що викликають дорогі 404 відповіді?
Віддавайте 404 дешево, кешуйте очевидні probe-шляхи і рейт-лімітуйте зловмисні патерни. Тримайте обробник 404 статичним і уникайте бекенд-залежностей.
Чому ми бачимо багато 404 для /wp-login.php, якщо ми не використовуємо WordPress?
Це звичний фоновий шум від сканерів. Розгляньте це як можливість зекономити: віддавайте мінімальний кешований 404 і подумайте про WAF-правила.
Як зрозуміти, що CDN кешує 404 неправильно?
Перевіряйте заголовки на кшталт Age і статус кешу CDN. Порівнюйте поведінку edge і origin, обминаючи CDN (коли можливо) і переглядаючи політику cache-control по шляху.
Наш SPA завжди віддає index.html. Як правильно обробляти 404?
Тримайте fallback SPA лише для відомих app-маршрутів. Невідомі шляхи повинні повертати 404 на сервері, або клієнтський роутер має відрендерити 404, тоді як сервер по можливості повертає статус 404.
Чи варто додавати кнопку «повідомити про битий лінк»?
Тільки якщо ви можете її надійно триажити і зупиняти зловживання. Якщо додавати — попередньо заповнюйте відсутній URL + referrer і маршрутуйте в чергу для перегляду.
Висновок: практичні наступні кроки
Непринизлива сторінка 404 — це не брендингова вправа. Це невелика функція надійності, що тримає користувачів у потоці і інформує вашу команду. Виконана правильно, вона зменшує навантаження підтримки, захищає SEO і перетворює «відсутнє» на «дієве».
Зробіть це далі, у такому порядку:
- Зробіть статуси правдивими: знищте soft 404 і catch-all редиректи на головну.
- Зробіть 404 дешевою: статична відповідь, мінімальні активи, без викликів до бекенду.
- Додайте інструменти відновлення: поле пошуку (через submit) і короткий перелік топ-завдань.
- Інструментуйте і переглядайте: логуйте referrer’и, відстежуйте топ відсутніх URL і налаштуйте алерти на спайки.
- Виправте джерела: спочатку внутрішні биті лінки, потім цільові редиректи для популярних зовнішніх помилок.
Якщо зробити лише одне: перестаньте ставитися до 404 як до мертвої кінцевої точки. Це діагностичний ендпоїнт з користувачем перед ним.