Ошибка 500 в REST API: как найти причину и исправить

Проверяем запрос, ответ, логи и путь через систему, чтобы найти конкретный слой, который возвращает 500.

REST API работал, а потом один запрос начал возвращать:

500 Internal Server Error

Или интеграция с сайтом внезапно перестала передавать данные, хотя URL API правильный, токен вроде бы на месте, а тот же запрос ещё вчера проходил.

Главная сложность ошибки 500 в REST API в том, что сам код 500 почти ничего не говорит о причине. По стандарту HTTP он означает только одно: сервер столкнулся с неожиданным условием и не смог выполнить запрос. Это не диагноз «сломалась база», «неверный токен» или «ошибка PHP».

Поэтому не начинайте с замены ключей API, увеличения таймаутов и переписывания интеграции.

Сначала выясните две вещи:

какой именно запрос падает и какой именно слой системы возвращает 500.

Это обычно сокращает диагностику с нескольких часов до вполне понятной последовательности действий.

Сначала повторите проблемный запрос отдельно

Если ошибка появилась внутри сайта, CRM, WordPress или собственного приложения, попробуйте выполнить тот же запрос отдельно от основной системы.

Подойдут Postman, curl или другой HTTP-клиент.

Например:

curl -i "https://example.com/api/orders/123"

Для POST-запроса с JSON:

curl -i -X POST "https://example.com/api/orders" \
  -H "Content-Type: application/json" \
  -d '{"test":true}'

Не вставляйте реальные API-ключи в команды, которые потом отправляете в поддержку, публикуете на форуме или пересылаете третьим лицам.

Здесь результат уже многое подскажет.

Если отдельный запрос тоже получает 500 — проблема воспроизводится непосредственно на API или по пути к нему.

Если в Postman всё работает, а сайт продолжает получать 500 — сравнивайте два фактических HTTP-запроса, а не начинайте чинить сервер целиком.

↑ К оглавлению

Не смотрите только на цифру 500 — откройте весь ответ

Очень полезная привычка: при ошибке API сохраняйте не только HTTP status.

Посмотрите:

response headers, response body и Content-Type.

Например, вы ожидали JSON:

{
  "error": "something went wrong"
}

а сервер вернул обычную HTML-страницу:

<html>
  <head>
    <title>500 Internal Server Error</title>
  </head>
</html>

Это важная зацепка.

Она может означать, что ответ сформировал не ваш API-контроллер, а веб-сервер, reverse proxy, hosting layer или другой промежуточный компонент.

Postman позволяет видеть код ответа, заголовки и body, а его Console показывает ещё и фактически отправленный запрос, redirects, proxy-настройки и сырой ответ сервера.

То есть вместо:

«API отдаёт 500»

у вас должно появиться что-то конкретнее:

«POST /api/orders с JSON доходит до приложения и падает в PHP»

или:

«500 возвращается до запуска обработчика».

Это уже совсем другая диагностика.

↑ К оглавлению

Определите, кто именно вернул ошибку

Между браузером и кодом REST API может находиться несколько слоёв:

браузер или приложение → CDN/WAF → nginx/Apache → PHP/framework → база данных → внешний API.

При облачной архитектуре между ними могут быть ещё API Gateway, serverless-функции и другие прокси.

Поэтому отсутствие ошибки в журнале приложения не означает, что никакой ошибки нет.

Есть свежий показательный кейс: запросы к API через AWS API Gateway периодически получали 500, но соответствующие Lambda-функции вообще не запускались. Диагностику пришлось переносить на уровень Gateway — запрос ломался раньше, чем попадал в приложение.

Отсюда простой принцип:

если в application log вообще нет проблемного запроса, поднимайтесь на один слой выше.

Проверьте access/error logs веб-сервера, proxy, gateway или платформы, через которую идёт запрос.

↑ К оглавлению

Найдите запрос в логах по времени

Самый полезный тест при REST API 500 часто выглядит скучно:

отправили запрос → запомнили точное время → сразу открыли журнал.

Не ищите просто все ошибки за неделю.

Нужна запись, появившаяся в ту же секунду.

Для PHP особенно интересны:

PHP Fatal error
Uncaught Error
Allowed memory size exhausted
Maximum execution time exceeded
Call to undefined method
Class ... not found

PHP официально поддерживает запись ошибок в server error log или отдельный файл. На production ошибки рекомендуется логировать, а не показывать посетителю вместе с потенциально чувствительной технической информацией.

Если в журнале есть конкретный файл, строка или stack trace — 500 перестаёт быть загадкой.

Теперь исправляется уже не «REST API», а конкретная ошибка.

↑ К оглавлению

Если всё сломалось сразу после обновления

Это один из случаев, где первым делом стоит смотреть не настройки API, а последний изменённый компонент.

Свежий реальный пример появился на WordPress.org летом 2026 года: после обновления Rank Math весь WordPress REST API начал падать, а запрос к endpoint настроек возвращал 500. В PHP log обнаружился fatal error из-за несовместимости сигнатур методов во входящей библиотеке.

Такие ситуации особенно характерны для систем, где REST API зависит от:

плагинов, PHP-пакетов, middleware, темы, кастомного кода или библиотек авторизации.

Если вчера API работал, а после конкретного обновления перестал, сначала зафиксируйте:

что обновилось, когда именно началась ошибка и какой компонент фигурирует в логе.

Не обновляйте сразу всё остальное в надежде «выровнять версии».

Иначе причин станет больше, а не меньше.

↑ К оглавлению

Postman работает, а сайт получает 500

Вот здесь часто находится очень полезная мелочь.

Снаружи запросы могут казаться одинаковыми:

POST /api/order

Но один клиент действительно отправляет:

Content-Type: application/json
Authorization: Bearer ...

а другой:

Content-Type: application/x-www-form-urlencoded

Или отличается body, метод, query-параметр, trailing slash, cookie или один автоматически добавленный header.

Postman в своей инструкции по 500 прямо рекомендует сверять HTTP method, headers, body parameters и query parameters с документацией API.

Причём смотреть лучше не только вкладку Headers. Postman может добавлять некоторые заголовки автоматически, включая Content-Type; фактически отправленные данные видны в Console.

↑ К оглавлению

Практический способ сравнения

Сделайте один запрос, который работает, и один, который падает.

Сравните:

URL

HTTP method

query parameters

request headers

Content-Type

Authorization

request body

cookies

redirects

Это единственный список, который действительно стоит пройти целиком.

Разница иногда оказывается в одном символе.

↑ К оглавлению

GET работает, а POST возвращает 500

Это хорошая развилка.

Если простой GET проходит, значит домен, DNS, TLS и базовая доступность API, скорее всего, уже работают.

POST добавляет новые места, где может появиться ошибка: body, сериализация, валидация, запись в базу, создание объекта, отправка файла или вызов стороннего сервиса.

Сначала посмотрите фактическое тело POST-запроса.

Например:

{
  "email": "user@example.com",
  "amount": 1500
}

и проверьте, действительно ли сервер получает JSON, а не строку или form-data.

Postman напоминает, что формат body и Content-Type связаны: для raw JSON клиент устанавливает соответствующий тип содержимого, а вручную заданный header может его переопределить.

В корректно написанном API неправильные пользовательские данные обычно должны приводить к подходящему 4xx, а не к 500. Но реальный backend может содержать ошибку, при которой неожиданное значение приводит к exception и уже превращается в Internal Server Error.

Поэтому странный входной параметр действительно может спровоцировать 500, но чинить в таком случае нужно обработку ошибки на сервере, а не объявлять неправильный JSON нормальным поведением API.

↑ К оглавлению

Не путайте ошибку авторизации с 500

При неправильном токене первым подозрением часто становится:

«Наверное, API отдаёт 500 из-за авторизации».

Иногда баг в backend действительно способен свалиться во время проверки токена. Но нормальный HTTP API должен использовать более подходящий клиентский код.

Например, WordPress для отсутствующей авторизации использует 401, а для уже авторизованного пользователя без необходимых прав — 403.

Поэтому если обычная ошибка авторизации внезапно стала 500, ищите не только токен.

Возможно, сломался сам authentication middleware, plugin или обработчик ошибки.

И ещё одна характерная история WordPress: веб-сервер может вообще не передать header Authorization PHP-приложению. В официальном REST API Handbook отдельно приведены настройки для Apache и nginx на такой случай.

Но и здесь сначала смотрите фактический ответ. Если API честно возвращает 401 — это уже не тема статьи про 500.

↑ К оглавлению

В WordPress REST API сначала проверьте /wp-json/

Для WordPress есть быстрый способ понять масштаб проблемы.

Откройте базовый REST endpoint:

https://example.com/wp-json/

Если он отвечает JSON, а падает только:

/wp-json/my-plugin/v1/action

круг поиска уже сузился до конкретного endpoint, плагина или его зависимостей.

Если 500 получает даже базовый REST API, проблема шире.

И это не мелочь: WordPress использует REST API не только для внешних интеграций. От него зависит часть административной функциональности, включая редактор. Официальная документация прямо предупреждает, что полностью отключать REST API нельзя без риска сломать функции WordPress Admin.

В обсуждениях WordPress встречаются ситуации, когда REST API 500 идёт рядом с поломкой корзины, аккаунта или административных функций после обновления плагина.

То есть сообщение в Site Health:

REST API encountered an unexpected result
500 Internal Server Error

может быть не отдельной косметической ошибкой, а симптомом более общей PHP-проблемы.

↑ К оглавлению

Один endpoint падает, остальные работают

Это хороший признак.

API целиком, скорее всего, не мёртв.

Сравните проблемный endpoint с рабочим.

Если:

GET /api/products

работает, а:

GET /api/products/1742

возвращает 500, проверьте данные именно объекта 1742.

Может оказаться, что в записи отсутствует обязательное поле, связанная сущность удалена, значение неожиданно null или обработчик попадает в ветку кода, которая редко выполняется.

Если падает только один маршрут:

не начинайте с перезагрузки сервера.

Сначала ищите то, что уникально именно для этого маршрута.

↑ К оглавлению

Ошибка возникает только на некоторых данных

Есть полезный тест, о котором легко забыть.

Отправьте тот же endpoint с другим объектом.

Например:

/api/orders/125

падает, а:

/api/orders/126

работает.

Это очень сильный сигнал.

Проблема может быть не в маршруте как таковом, а в конкретной записи: повреждённых данных, неожиданном формате, отсутствующей связи, некорректном символе или особом состоянии заказа.

В таком сценарии бесполезно часами перенастраивать nginx.

Сравните данные двух объектов и строку лога, которая появляется только для проблемного.

↑ К оглавлению

Ошибка 500 появляется иногда, а потом исчезает

Такие ошибки неприятнее постоянных.

Если один и тот же запрос то работает, то падает, фиксируйте:

точное время, endpoint, параметры, response headers и request ID — если сервер его возвращает.

Затем сопоставляйте это время с логами.

Причиной могут оказаться временные ошибки upstream, база данных, нехватка ресурсов, параллельные запросы или промежуточный gateway.

Важно не делать вывод:

«повторил запрос — заработало, значит всё нормально».

Это означает только, что проблема непостоянная.

В свежем кейсе с API Gateway разные endpoints падали случайным образом, а повторный запрос проходил. Ключевой подсказкой оказалось то, что failed request вообще не доходил до Lambda.

То есть при плавающем 500 особенно важно определить границу, до которой запрос реально дошёл.

↑ К оглавлению

500, 502 и 504 — это не одно и то же

Эти коды часто называют одной фразой «серверная ошибка», хотя для диагностики разница принципиальная.

500 Internal Server Error означает неожиданную ошибку при выполнении запроса.

502 Bad Gateway означает, что proxy/gateway получил некорректный ответ от upstream.

504 Gateway Timeout — что gateway не дождался ответа upstream вовремя.

Поэтому если nginx показывает 504, не стоит открывать статью про REST API 500 и сразу искать PHP fatal error.

А если API постоянно возвращает именно 500 при обращении к внешнему сервису, проверьте, не скрывает ли ваш код реальную upstream-проблему за универсальным статусом 500.

Хорошая обработка ошибок должна сохранять смысл сбоя, а не превращать всё подряд в Internal Server Error.

↑ К оглавлению

Не увеличивайте timeout как первую реакцию

API отвечает долго, потом появляется ошибка — рука тянется поставить timeout побольше.

Иногда это действительно необходимо.

Но сначала выясните, где заканчивается время.

Если PHP ждёт зависший SQL-запрос, внешний сервис или блокировку, увеличение timeout просто заставит пользователя ждать дольше.

Если же клиентский timeout слишком короткий, клиент вообще может прекратить ожидание раньше ответа сервера. Postman позволяет отдельно настраивать timeout запроса, но это клиентская настройка и она не исправляет серверный exception.

Сначала лог и время выполнения.

Потом timeout.

Не наоборот.

↑ К оглавлению

Что делать, если логи пустые

Пустой application log — тоже результат.

Проверьте access log.

Если запрос там есть, но в логе приложения ничего нет, ошибка может происходить до нужной точки логирования.

Если запрос отсутствует и там — смотрите предыдущий слой: CDN, firewall, load balancer или gateway.

Если сервер отвечает собственной HTML-страницей 500 — смотрите журнал веб-сервера.

Если request ID присутствует — используйте его для поиска именно этой транзакции.

Главный принцип остаётся тем же:

искать ошибку там, где запрос исчезает, а не там, где удобнее открыть лог.

↑ К оглавлению

Когда 500 должен исправлять разработчик API

Если вы интегрируете чужой сервис и подтвердили, что запрос соответствует его документации, а endpoint стабильно возвращает 500, не пытайтесь чинить чужой сервер.

Сохраните:

точное время запроса

endpoint

HTTP method

status

response body

request ID

обезличенный пример body

Секреты, Authorization headers, API keys и персональные данные перед отправкой уберите.

Postman при сохраняющейся 500 после проверки конфигурации запроса тоже рекомендует обращаться к владельцу API.

Такой отчёт гораздо полезнее сообщения:

«Ваш API не работает».

↑ К оглавлению

А если REST API пишете вы сами

Здесь есть ещё одна сторона проблемы.

Клиент не должен получать stack trace, SQL, внутренние пути сервера или секретные данные просто потому, что произошла ошибка.

При этом ответ API должен оставаться достаточно информативным для диагностики.

Для стандартизированного машинно-читаемого описания HTTP API errors существует формат Problem Details, определённый RFC 9457.

Но даже хороший JSON-ответ пользователю не заменяет серверный лог.

Клиенту можно сообщить безопасное описание и request ID.

А разработчику в журнале оставить exception, stack trace и внутренний контекст.

Это намного полезнее универсального:

{
  "error": "Internal Server Error"
}

без единой возможности понять, что произошло.

↑ К оглавлению

Как проверить REST API 500 за несколько минут

Начните с проблемного запроса отдельно от сайта.

Посмотрите status, headers и body.

Затем сравните его с рабочим запросом.

После этого найдите точно тот же момент времени в server/application logs.

Если запроса в приложении нет — переходите к proxy или gateway.

Если приложение получило запрос — чините конкретный exception, который показывает log.

Если Postman работает — сравнивайте фактически отправленные headers, body и method.

Если падает только один endpoint или одна запись — не трогайте весь сервер.

Так 500 Internal Server Error быстро превращается из общей надписи в конкретную точку поломки.

↑ К оглавлению

Чего не стоит делать

Не меняйте одновременно API key, PHP, nginx и код интеграции.

Не отключайте firewall только потому, что получили 500.

Не увеличивайте memory limit или timeout без признаков, что проблема именно там.

Не публикуйте полный Authorization header и реальные токены вместе с логами.

Не считайте любой 5xx одной и той же ошибкой.

И не принимайте временно успешный повторный запрос за исправление плавающего сбоя.

↑ К оглавлению

Что в итоге

При ошибке 500 в REST API главный вопрос не:

«Какая настройка API неправильная?»

А:

«На каком шаге обработки запрос перестал выполняться?»

Начните с точного воспроизведения.

Посмотрите весь response.

Сравните рабочий и нерабочий запрос.

Найдите тот же момент в логах.

И только после этого меняйте код или конфигурацию.

Если ошибка появилась после обновления — первым делом проверяйте новый компонент и fatal errors.

Если Postman работает, а сайт нет — сравнивайте запросы.

Если один endpoint падает, а остальные нет — проверяйте его обработчик и данные.

Если application log молчит — поднимайтесь к proxy или gateway.

В REST API хороший поиск причины почти всегда начинается не с длинного списка возможных неисправностей, а с одного конкретного запроса и его пути через систему.

↑ К оглавлению
↑ К оглавлению

Частые вопросы

Что означает ошибка 500 в REST API?

500 Internal Server Error означает, что сервер столкнулся с неожиданной ситуацией и не смог выполнить запрос. Сам статус не сообщает точную причину — её нужно искать в response и серверных логах.

Может ли неправильный REST API-запрос вызвать 500?

Да, если серверный код неправильно обрабатывает неожиданные данные и падает с exception. Но для обычных ошибок клиентского запроса корректный API должен использовать подходящий 4xx. Поэтому 500 в ответ на плохие данные часто указывает ещё и на проблему обработки ошибок на backend.

Почему REST API работает в Postman, но не работает на сайте?

Обычно нужно сравнить реальные HTTP requests: method, URL, headers, authorization, Content-Type, query parameters и body. Postman Console показывает фактически отправленные заголовки и сырой ответ, включая автоматически добавленные параметры.

Что проверять первым при REST API 500 после обновления WordPress?

Сначала воспроизведите ошибку и сразу посмотрите PHP error log. Свежие реальные случаи показывают, что обновление плагина может вызвать fatal error и положить REST API целиком.

Почему в логах приложения нет ошибки 500?

Возможно, запрос вообще не дошёл до приложения. Тогда проверяйте reverse proxy, веб-сервер, API gateway или другой предыдущий слой. Такой сценарий встречается и в реальных облачных API.

REST API 500 и 504 — это одно и то же?

Нет. 500 — неожиданная серверная ошибка. 504 означает, что gateway или proxy не получил своевременный ответ от upstream. 502 означает некорректный ответ upstream. Для каждой ситуации путь диагностики разный.

↑ К оглавлению

Нужна помощь с REST API?

Если ошибка повторяется, endpoint недоступен или логи не показывают причину, передайте специалисту URL, время ошибки, запрос и обезличенный ответ.

↑ К оглавлению