Алексей Смирнов
Старший инженер по интеграциям и архитектуре API
01Введение

Ошибка «не удалось распарсить JSON» встречается в логах фронтенда, бэкенда и при интеграциях между сервисами. Внешне это простая формулировка, но под ней скрывается широкий набор причин: от лишней запятой в ответе до получения HTML‑страницы с сообщением об ошибке. Панику лучше заменить выверенной процедурой действий, которая снижает время простоя и объем ручной работы.
Ниже приведена детальная методика для последовательного расследования и устранения таких инцидентов. Приведены практические проверки для работы с HTTP‑заголовками, кодировками и контрактами, рекомендации по логированию и валидации, а также конкретный мини‑кейс из интеграции с банковским провайдером. Материал адаптирован под реалии с legacy‑системами, банковскими шлюзами и требованиями к защите персональных данных.
02Содержание
- Введение
- Почему «Не удалось распарсить JSON» — основные причины
- HTTP‑заголовки, кодировки и BOM: что проверять в первую очередь
- Серверные ответы в HTML и прокси — как отличить и исправить
- Несоответствие схемы (контракта) — почему это опасно и как предотвратить
- Инструменты и методики диагностики: набор для практики
- Подходы к обработке ошибок: строгая валидация против lenient‑парсинга
- Частые ошибки и компактный чек‑лист для быстрого восстановления
- Практические советы, которые экономят время
- Мини‑кейс: расследование инцидента при интеграции с банком
- Рекомендованные практики внедрения в рабочий процесс
- Заключение
- Часто задаваемые вопросы
03Почему «Не удалось распарсить JSON» — основные причины

Чаще всего причина кроется в теле ответа сервера. Вместо ожидаемого JSON приходит HTML‑страница с ошибкой, стек‑трейс или просто текст. Иногда Content‑Type указан неверно, и парсер отказывается работать в строгом режиме. Важно сначала проверить код ответа и «сырое» тело, затем — заголовки и дополнительные промежуточные точки в цепочке доставки запроса.
Ниже — свод типичных причин с признаками, по которым можно быстро диагностировать происхождение ошибки. В реальных проектах около 60–70% таких инцидентов связаны с серверной частью или прокси, а не с клиентским парсером, особенно при интеграциях с банками и госсервисами, где вместо JSON нередко приходит HTML‑страница авторизации, CAPTCHA или страница с сообщением об ошибке.
| Критерий | Описание | Комментарий эксперта |
|---|---|---|
| HTML вместо JSON | Ответ начинается с ''<!DOCTYPE html>'' или ''<html>'' | Типично при ошибках 500/404, прокси или авторизации через SSO; часто видно визуальный текст с трассировкой |
| Невалидный JSON | Лишняя запятая, незакрытая строка, неверные кавычки | Появляется при ручной сборке JSON, недостаточной сериализации или при спорадических ошибках при форматировании |
| Проблемы с кодировкой/BOM | Первые байты — BOM (0xEF,0xBB,0xBF) или непредвидённая CP1251‑строка | Часто при экспортах из 1С и старых систем; BOM невидим в текстовом просмотре, но ломает строгие парсеры |
| Неправильный Content-Type | Content-Type: text/html вместо application/json | Маскирует проблему; парсер может игнорировать или переключиться в lenient режим, что ведёт к непредсказуемым последствиям |
04HTTP‑заголовки, кодировки и BOM: что проверять в первую очередь

Заголовки Content‑Type и charset — первичное место для проверки. Если сервер возвращает Content‑Type: text/html, но тело — JSON, парсер может вести себя по‑разному в зависимости от реализации. Правильная настройка заголовков снижает число инцидентов вдвое. Важно также отслеживать Transfer‑Encoding и сжатие (gzip), которые при неверной конфигурации прокси могут привести к обрезке потока и порче JSON.
Кодировка — отдельная тема. UTF‑8 с BOM добавляет невидимые байты в начало тела и вызывает ошибку парсера; старые системы иногда возвращают CP1251. Простые меры — удалить BOM при генерации и привести поток к UTF‑8. В серверных фреймворках есть стандартные функции для этого; для интеграционных скриптов используются iconv или аналогичные утилиты.
| Критерий | Что смотреть | Как исправить |
|---|---|---|
| Content-Type | application/json; charset=utf-8 | Настроить сервер (Nginx/Express/Java) — явно выставлять заголовок, проверить вывод статических прокси и middleware |
| Charset / BOM | В начале тела есть байты EF BB BF | Удалять BOM при генерации; в Node.js: body = body.replace(/^\\uFEFF/, ''''); в bash: sed ''1s/^\\xEF\\xBB\\xBF//'' |
| Transfer-Encoding | chunked или неверная длина | Проверить прокси, балансировщик и конфигурацию keepalive; убедиться, что Content‑Length совпадает с фактическим телом |
05Серверные ответы в HTML и прокси — как отличить и исправить

Сообщение вида "Unexpected token < in JSON at position 0" почти всегда означает, что вместо JSON пришёл HTML. Это быстрый способ локализации: если в начале тела встречается символ "<", откройте тело в браузере или в визуализаторе HTML. Причины могут быть различными: падение сервиса, страница входа через SSO, подмена со стороны прокси или балансировщика, возвращающего страницу ошибки.
HTTP‑код важен, но не решающий. Даже при коде 200 может приходить HTML с описанием ошибки. При 4xx и 5xx чаще всего возвращают HTML с объяснением. При расследовании сначала смотрят код, затем «сырое» тело. Если корпус ответа — HTML, полезно открыть первые 1000 символов, чтобы увидеть источник и стек‑трейс.
| Симптом | Возможная причина | Рекомендуемое действие |
|---|---|---|
| Unexpected token <...> | HTML вместо JSON | Сохранить тело, открыть в браузере, изучить заголовки и код ответа; найти точку, где контент преобразуется |
| Пустой ответ | Таймаут, обрыв соединения или неверный Content-Length | Проверить сетевые логи, балансировщик и рестарт сервисов; включить подробные логи на прокси |
| JSON с ошибочной структурой | Ошибка сериализации | Включить подробное логирование сериализации на сервере; проверить тесты формата |
06Несоответствие схемы (контракта) — почему это опасно и как предотвратить

Даже корректный JSON может не соответствовать ожиданиям приложения: изменилось имя поля, формат даты или тип ID. Такие изменения ломают функционал клиентов и в банковской и госсреде приводят к серьёзным последствиям. Фиксация контракта и автоматическая проверка совместимости позволяют обнаруживать разрывы в интеграции до релиза.
Инструменты вроде JSON Schema, Pact и OpenAPI помогают формализовать ожидания. Их применяют в CI: при каждом изменении проверяются контракты и генерируются отчёты о несовместимости. Это особенно важно при взаимодействии с внешними провайдерами, где незаметное изменение поля приводит к цепочке ошибок.
| Критерий | Инструмент | Комментарий |
|---|---|---|
| Описание схемы | OpenAPI / Swagger | Удобно для REST; генерирует документацию и примеры, помогает понять возможные ответы провайдера |
| Контрактное тестирование | Pact | Позволяет протестировать совместимость провайдера и потребителя в изолированном окружении |
| Валидация формата | JSON Schema | Быстрая и предсказуемая проверка структуры и типов на ранних стадиях |
07Инструменты и методики диагностики: набор для практики
Для оперативного расследования необходимы простые инструменты. Curl и HTTPie позволяют получать и сохранять raw‑ответ. JQ и jsonlint — быстро проверяют валидность JSON. Postman и Insomnia удобны для интерактивных проверок и последовательных тестов. Такой набор позволяет локализовать проблему в течение минут при последовательной проверке кода, заголовков и тела.
Логирование — ключевой элемент. Сохраняйте raw‑тела в защищённом хранилище и привязывайте их к request id. Обязательно маскируйте персональные данные перед длительным хранением. Корректный набор логов уменьшает количество догадок и ускоряет расследование в 2–3 раза.
| Инструмент | Задача | Пример использования |
|---|---|---|
| curl | Запрос и сохранение raw ответа | curl -sS -D - ''URL'' -o response.raw |
| jq | Парсинг и форматирование JSON | cat response.raw | jq . (или jq -e . для проверки валидности) |
| Postman | Интерактивные запросы и коллекции | Создать коллекцию тестов, проверяющих соответствие ответов схеме |
08Подходы к обработке ошибок: строгая валидация против lenient‑парсинга
Существует две концепции: строгая валидация, когда парсер отвергает всё, что не соответствует схеме, и lenient‑парсинг, когда парсер допускает мелкие несовпадения ради устойчивости работы. Для публичных API, аудита и банковских интеграций предпочтительна строгая валидация — она выявляет проблемы на ранней стадии и не позволяет дефектам скрываться под временными исправлениями.
Для внутренних сервисов с высокими SLA иногда уместен lenient‑режим: он уменьшает количество простоев при частичных ошибках. В таком случае внедряют флаги деградации и логирование всех погрешностей, чтобы быстро фиксировать и устранять нарушения контракта. Рекомендуется комбинировать подходы: строгая валидация в CI и у поставщиков, lenient‑режим с контролируемым доступом в рантайме.
| Критерий | Строгая валидация | Lenient‑парсинг |
|---|---|---|
| Устойчивость | Меньше неожиданных состояний | Меньше простоев при частичных ошибках |
| Выявление проблем | Раннее и явное | Может маскировать дефекты |
| Сценарий применения | Банки, госуслуги, публичные API | Внутренние сервисы с критичными SLA |
09Частые ошибки и компактный чек‑лист для быстрого восстановления
Ниже приведён компактный практический чек‑лист, который помогает восстановить работу за минимальное время. В кризис важно действовать по упорядоченному списку проверок и не заниматься бессистемными правками в коде. Используйте карточку проверок в тикете инцидента и следуйте приоритетам.
Таблица содержит типичные проверки и соответствующие действия — её удобно хранить в шаблоне инцидента и применять повторно при каждой подобной ошибке.
| № | Проверка | Действие |
|---|---|---|
| 1 | HTTP‑код ответа | Если ≠200, сохранить тело и уведомить владельца сервиса; проверить ретраи и поведение прокси |
| 2 | Первые 200 байт тела | Проверить на HTML, BOM и необычные символы; открыть в браузере при наличии HTML |
| 3 | Content-Type | Убедиться, что указано application/json; charset=utf-8; при несоответствии — исправить конфигурацию сервера |
| 4 | Валидность JSON | Запустить jq/jsonlint и сохранить вывод; при ошибке включить подробное логирование сериализации |
| 5 | Схема | Проверить соответствие JSON Schema / OpenAPI; сравнить с последними контрактами |
| 6 | Логи прокси/балансировщика | Проверить изменения тела по цепочке, найти место подмены или добавления HTML |
10Практические советы, которые экономят время
Ниже — конкретные практики, упрощающие работу с ошибками парсинга в продакшне. Эти приёмы проверены в проектах разного масштаба и показывают стабильный эффект при правильном внедрении.
Особое внимание уделено адаптации для интеграций с legacy‑системами и банковскими шлюзами, где встречаются проблемы с кодировкой и неожиданные HTML‑ответы.
| Практика | Описание | Почему важно |
|---|---|---|
| Логировать raw body | Сохранять первые N байт и весь body в защищённом хранилище с маской чувствительных полей | Помогает быстро понять контекст ошибки и вести расследование без доступа к продакшен‑среде |
| JSON Schema в CI | Валидация ответов и контрактов при каждом PR | Ловит изменения контракта до релиза, предотвращая поломки у потребителей |
| Health checks и timeouts | Настроить корректные health‑check''и и таймауты, чтобы балансировщик не возвращал HTML страницы обслуживания | Уменьшает вероятность получения HTML от балансировщика и предотвращает подмену ответов |
11Мини‑кейс: расследование инцидента при интеграции с банком
Ситуация: магазин получил множество ошибок парсинга в пиковый период, клиенты не могли завершить оплату. Логи клиентского приложения выдавали «не удалось распарсить JSON». Команда применила стандартный чек‑лист и нашла HTML‑страницу с сообщением об устаревшем сертификате провайдера. HTTP‑код был 200 из‑за промежуточного прокси, который подменял ответ.
Последовательные действия команды включали сохранение raw‑ответа, открытие тела в браузере, идентификацию HTML с сообщением об ошибке SSL, связь с техподдержкой банка и анализ логов балансировщика. В результате корректировка health check и обновление сертификата восстановили корректную доставку JSON. От детекции до полного восстановления прошло 1 час 20 минут.
| № | Действие команды | Результат |
|---|---|---|
| 1 | Разбор логов и сохранение raw body (первые 500 байт) | Обнаружен HTML с сообщением об ошибке SSL |
| 2 | Проверка инфраструктуры: логи балансировщика и прокси | Подмена ответа из‑за устаревшего сертификата в промежуточном звене |
| 3 | Связь с провайдером и обновление сертификата | Проблема решена, возвращается корректный JSON |
12Рекомендованные практики внедрения в рабочий процесс
Для минимизации подобных инцидентов рекомендуется внедрять несколько простых и проверенных практик: автоматическая валидация контрактов в CI, шаблонное логирование raw‑тел с маской чувствительных данных, ежедневные мониторинги ключевых эндпоинтов на предмет изменений формата и заголовков, а также регламенты взаимодействия с внешними поставщиками.
Примеры конкретных действий в инфраструктуре: в Nginx — явно выставлять заголовок ''Content-Type: application/json; charset=utf-8'' для API‑роутов; в приложении — убирать BOM при генерации ответов и приводить строки к UTF‑8; в CI — запускать скрипты, проверяющие первые байты ответов и соответствие JSON Schema.
— Алексей Смирнов
— Алексей Смирнов
— Алексей Смирнов
13Заключение
Ошибка «не удалось распарсить JSON» — лишь симптом. Системный подход к логированию, проверке заголовков и внедрению контрактов существенно сокращает количество таких инцидентов. Набор простых инструментов, шаблонов расследования и автоматических проверок помогает быстро восстановить работу и минимизировать ущерб.
Рекомендуется: внедрить JSON Schema в CI, логировать raw‑тела с маской персональных данных, настроить корректные заголовки и health‑checks. По запросу можно подготовить пример CI‑теста для проверки endpoint''ов и шаблон карточки расследования для инцидент‑менеджеров.
14FAQ
1. Что делать сначала при ошибке «не удалось распарсить JSON»?
Сначала посмотреть HTTP‑код и сохранить raw‑ответ; часто этого достаточно для локализации проблемы.
2. Почему парсер жалуется на «Unexpected token <»?
Это почти всегда означает HTML вместо JSON; проверьте тело и заголовки.
3. Как бороться с BOM в ответе?
Удаляйте BOM на стадии генерации ответа или обрезайте первые байты перед парсингом в рантайме, например, средствами фреймворка или простыми утилитами.
4. Можно ли временно включить lenient‑парсинг?
Это допустимо для внутренних потребителей с контрольным флагом и обязательной записью всех отклонений; категорически не рекомендуется для публичных API и банковских интеграций.
5. Какие инструменты использовать для проверки?
Curl/HTTPie, jq, jsonlint, Postman; добавьте автоматические проверки в набор оперативной поддержки.
6. Как не нарушать законы при логировании?
Маскируйте персональные данные и храните логи в защищённом хранилище согласно политике безопасности и требованиям регулятора.
7. С чего начать улучшение процессов?
Начните с внедрения чек‑листа инцидента, добавьте проверку JSON Schema в CI и настройте шаблон логирования raw‑тела с маскировкой персональных данных.
1. Что делать сначала при ошибке «не удалось распарсить JSON»? Сначала посмотреть HTTP‑код и сохранить raw‑ответ; часто этого достаточно для локализации проблемы.
2. Почему парсер жалуется на «Unexpected token <»? Это почти всегда означает HTML вместо JSON; проверьте тело и заголовки.
3. Как бороться с BOM в ответе? Удаляйте BOM на стадии генерации ответа или обрезайте первые байты перед парсингом в рантайме, например, средствами фреймворка или простыми утилитами.
4. Можно ли временно включить lenient‑парсинг? Это допустимо для внутренних потребителей с контрольным флагом и обязательной записью всех отклонений; категорически не рекомендуется для публичных API и банковских интеграций.
5. Какие инструменты использовать для проверки? Curl/HTTPie, jq, jsonlint, Postman; добавьте автоматические проверки в набор оперативной поддержки.
6. Как не нарушать законы при логировании? Маскируйте персональные данные и храните логи в защищённом хранилище согласно политике безопасности и требованиям регулятора.
7. С чего начать улучшение процессов? Начните с внедрения чек‑листа инцидента, добавьте проверку JSON Schema в CI и настройте шаблон логирования raw‑тела с маскировкой персональных данных.
15Об авторе
Алексей Смирнов — старший инженер по интеграциям и архитектуре API. Специализируется на построении надёжных интеграционных слоев, API‑контрактов и механизмах мониторинга для критичных сервисов.
Опыт работы более 12 лет: проекты в e‑commerce, банковской сфере и государственных интеграциях. Участвовал в построении архитектуры обмена данными между крупными сервисами, внедрял контрактное тестирование, автоматизацию проверок и процесс логирования, совместимого с регуляторными требованиями. Ведёт практические воркшопы и консультации по расследованию инцидентов и повышению устойчивости интеграций.
