Коды ошибок push-реле (push-relay)
Возвращаются центральным push-реле (W3-RLY-01, ARCHITECTURE, раздел 6) в виде application/problem+json
(code, title, status, необязательно detail). Поле detail никогда не содержит токены устройств, ключи,
сведения о звонящих или содержимое уведомления. Тест every_relay_code_is_documented в
relay/crates/push-relay-core/src/error.rs поддерживает эту страницу и код в соответствии друг с другом.
Push, который дошёл до APNs или FCM, никогда не считается ошибкой: POST /v1/push отвечает 200 с result
accepted, invalid_token, rejected или failed, а также статусом вышестоящего сервиса и кодом причины
(например, BadDeviceToken или UNREGISTERED). Коды ниже относятся к запросам, которые реле отклонило до
отправки. Каждый отклонённый push освобождает свой ключ идемпотентности, поэтому АТС может повторить его с тем же
ключом.
Результаты отправки (W3-RLY-02)
Каждый push, который реле отправило вышестоящему сервису, получает ровно один result. Он возвращается в ответе
на push, хранится 30 дней в relay_deliveries, позже читается через POST /v1/receipts/query и учитывается в
mpbx_relay_pushes_total{platform,kind,result}. upstream_status и upstream_reason относятся к последней попытке.
result | Значение | Типичные ответы вышестоящего сервиса | Повторяет реле | Что делает АТС (W3-PUSH-01) |
|---|---|---|---|---|
accepted | APNs или FCM приняли push к доставке. Это ещё не доказательство, что телефон его получил: это подтверждение (delivered_at). | APNs 200; FCM 200 | — | Продолжать звонить; записать идентификатор push; отметить доставку, когда придёт подтверждение. |
invalid_token | Токен устройства недействителен. Реле помечает устройство как недействительное; последующие push отвечают RELAY-DEVICE-INVALID, пока приложение не зарегистрирует новый токен. | APNs 400 BadDeviceToken, 400 DeviceTokenNotForTopic, 410 Unregistered; FCM 404, UNREGISTERED, SENDER_ID_MISMATCH; FCM INVALID_TOKEN_FORMAT (локальная проверка) | нет | Пометить устройство как degraded, сообщить пользователю, позвонить на другие устройства. |
rejected | APNs или FCM отклонили push по другой постоянной причине (полезная нагрузка, тема, наши учётные данные после одного обновления). Повтор того же push не поможет. | APNs 400 с другими причинами, 403 ExpiredProviderToken / InvalidProviderToken дважды; FCM 400 INVALID_ARGUMENT, 401 дважды, THIRD_PARTY_AUTH_ERROR дважды; локальные для реле provider_token, oauth_sign, oauth_failed (4xx) | токен провайдера/OAuth обновляется один раз | Позвонить на другие устройства; операторы видят mpbx_relay_pushes_total{result="rejected"}. |
failed | Временные сбои, пока не закончился бюджет повторов (3 попытки, 5 с для вызовов, 15 с для уведомлений). | 429, 500, 503; FCM QUOTA_EXCEEDED, UNAVAILABLE, INTERNAL; локальные для реле connect, timeout, oauth_connect, oauth_body | да, со случайной нарастающей задержкой и Retry-After | Повторить в пределах окна звонка с тем же ключом идемпотентности, параллельно позвонить на другие устройства. |
upstream_reason всегда является кодом причины вышестоящего сервиса или реле из этой таблицы (не более 64 символов),
но никогда не содержимым полезной нагрузки.
Подтверждения доставки (W3-RLY-02)
Приложение подтверждает каждый push запросом POST /v1/receipts {push_id, receipt} (поля полезной нагрузки p и
r). Корректное подтверждение отвечает 204, в том числе когда оно повторное (записывается один раз). АТС читает
результаты и подтверждения подписанным запросом POST /v1/receipts/query {push_ids} (не более 200 идентификаторов);
идентификаторы других экземпляров, неизвестные идентификаторы и идентификаторы старше 30 дней хранения в ответе
отсутствуют.
| Код | HTTP | Значение | Что делать |
|---|---|---|---|
RELAY-AUTH-MISSING | 401 | Заголовок подписи (x-mpbx-instance или x-mpbx-public-key, x-mpbx-timestamp, x-mpbx-nonce, x-mpbx-signature) отсутствует или сформирован неверно. | Используйте mpbx-push-relay-client, который подписывает каждый запрос (mpbx-relay-sig-v1). |
RELAY-AUTH-SKEW | 401 | Отметка времени запроса отличается от часов реле больше чем на 300 с (в описании указано время реле), либо она старше эпохи повтора реле: запрос подписан до переключения на другой регион или перезапуска Valkey (W10-RLY-01). | Исправьте часы хоста АТС (NTP). После переключения подпишите запрос заново (АТС делает это при каждом повторе). |
RELAY-AUTH-REPLAY | 401 | Этот экземпляр уже использовал nonce в течение последних 10 минут: повторённый или продублированный запрос. | Отправляйте каждый запрос с новым nonce (это делает клиент). Повтор push использует тот же ключ идемпотентности, но не тот же nonce. |
RELAY-AUTH-INVALID | 401 | Подпись не проверяется либо идентификатор экземпляра неизвестен (эти два случая намеренно не различаются). | Проверьте, что MPBX_RELAY_INSTANCE_KEY — это зарегистрированный ключ. Если ключ заменили без ротации, зарегистрируйте экземпляр заново (новый ключ получит новый идентификатор экземпляра); для сохранения устройств выполните ротацию через POST /v1/instances/rotate-key. Ротация ключа, доказательство нового ключа которой не проверяется, тоже возвращает этот код. |
RELAY-ENROLL-CODE-REQUIRED | 403 | Это реле принимает регистрацию только с кодом активации (MPBX_RELAY_ENROLLMENT=code_required). | Запросите код активации у MonoPbx и выполните ручную активацию. |
RELAY-ENROLL-CODE-INVALID | 403 | Код активации неизвестен, уже использован или истёк. Коды одноразовые. | Запросите новый код (push-relay activation-code create на реле). |
RELAY-ENTITLEMENT-EXPIRED | 403 | Право было отозвано, и его 30-дневный льготный период истёк. Push явно отклоняется, никогда не отбрасывается молча. | Свяжитесь с MonoPbx. В льготный период push продолжают проходить, а каждый ответ содержит x-mpbx-entitlement: grace; ends=.... |
RELAY-BAD-REQUEST | 400 | Тело не является корректным JSON для этой конечной точки, либо поле неверно (например, push вызова без call_uuid, токен неверной формы, push для iOS без соответствующего токена). Описание называет поле. | Исправьте запрос. |
RELAY-BODY-TOO-LARGE | 413 | Тело больше 16 КиБ. | Запросы небольшие; это ошибка клиента. |
RELAY-DEVICE-NOT-FOUND | 404 | push_ref не существует для этого экземпляра (он может принадлежать другому экземпляру, что не раскрывается), либо конечная точка не существует. | Зарегистрируйте устройство заново и сохраните новый push_ref. |
RELAY-DEVICE-INVALID | 410 | APNs или FCM ранее сообщили, что токен устройства недействителен, поэтому реле перестало его использовать. | Приложение должно отправить новый токен; зарегистрируйте его заново (тот же device_id сохраняет push_ref). |
RELAY-DEVICE-LIMIT | 409 | У экземпляра уже максимальное число зарегистрированных устройств (по умолчанию 20 000). | Удалите устройства, которых больше нет (DELETE /v1/devices/{push_ref}). |
RELAY-IDEMPOTENCY-CONFLICT | 409 | Ключ идемпотентности уже использован с другим телом запроса. | Используйте новый ключ для другого push (клиент использует <call_uuid>:<kind>:<push_ref>). |
RELAY-IDEMPOTENCY-IN-FLIGHT | 409 | Запрос с тем же ключом идемпотентности ещё отправляется. | Дождитесь первого ответа; повторите после Retry-After. |
RELAY-RATE-LIMITED | 429 | Превышена частота push на экземпляр (20/с, пакет 200), операции с устройствами (600/мин) или попытки регистрации (10/мин с одного адреса). | Повторите после Retry-After. |
RELAY-QUOTA-DAILY | 429 | Достигнут суточный жёсткий лимит экземпляра (по умолчанию 100 000 push за день UTC). | Повторите после Retry-After (со следующего дня UTC) или свяжитесь с MonoPbx. |
RELAY-QUOTA-DEVICE | 429 | На одно устройство отправлено более 30 push в минуту. | Повторите после Retry-After; проверьте АТС на наличие цикла push. |
RELAY-PLATFORM-UNAVAILABLE | 503 | У реле не настроены учётные данные APNs (iOS) или FCM (Android), либо ключ шифрования Web Push (MPBX_RELAY_WEB_PUSH_KEK_PATH, для браузеров). Также выводится push-relay serve, когда настроенный ключ не удаётся загрузить. | Оператор: задайте MPBX_RELAY_APNS_* или MPBX_RELAY_FCM_* (docs/guides/push-relay.md). |
RELAY-WEB-ENDPOINT-REFUSED | 422 | Регистрация веб-устройства (браузера), конечную точку Web Push которой реле не будет вызывать (W6-RLY-WEB, защита от SSRF): не https, IP-адрес вместо имени хоста, данные пользователя или порт, отличный от 443, в URL, хост, который не входит в известные службы push (MPBX_RELAY_WEB_PUSH_HOSTS), либо ключ подписки неверного размера. Та же проверка выполняется перед каждым push, и хост, который разрешается в частный, loopback или link-local адрес, отклоняется и тогда. | АТС: сообщите пользователю, что служба push этого браузера не поддерживается (вызовы по-прежнему звонят, пока открыт MonoPbx). Оператор: добавьте суффикс хоста службы push в MPBX_RELAY_WEB_PUSH_HOSTS, только если это настоящая публичная служба push. |
RELAY-RECEIPT-INVALID | 401 | Токен подтверждения не совпадает с идентификатором push, либо идентификатор push не является идентификатором push реле. Токены привязаны к одному push. | Приложение: отправьте значения p и r push точно в том виде, в каком их получило. |
RELAY-RECEIPT-EXPIRED | 410 | Push старше 25 часов; подтвердить его уже нельзя. | Ничего делать не нужно; отбросьте подтверждение. |
RELAY-RECEIPTS-UNAVAILABLE | 503 | У реле нет ключа подтверждений (MPBX_RELAY_RECEIPT_KEY_PATH), поэтому push не содержат токена подтверждения. | Оператор: настройте ключ (docs/guides/push-relay.md). АТС считает accepted последним известным состоянием. |
RELAY-UNAVAILABLE | 503 | База данных реле или Valkey недоступны. | Повторите попытку; тем временем АТС продолжает звонить на активные устройства (ARCHITECTURE 11.3). |
RELAY-INTERNAL | 500 | Непредвиденная ошибка реле (записана в журнал реле). | Повторите попытку; сообщите, если ошибка сохраняется. |