provider_unavailable
HTTP 503 retryable: true REST and MCP
A dependency outside this system, the mail provider, did not respond usefully, so the operation could not be completed now.
Why it happens
This code is reserved for the provider boundary specifically, which is why it is distinct from temporarily_unavailable. It covers provisioning that is not configured, an inbound retrieval that failed retryably, and attachment metadata or content that the provider could not supply. The case worth understanding is the ambiguous one: when a provider inbox creation cannot be confirmed either way, the address reservation is kept and the inbox is left paused rather than released, and the response tells you to contact support with the request id before retrying. That is not a generic outage message, it is an instruction not to retry into an unknown state.
Every condition below was read in the implementation at the file and line given. They are the branches that raise this code, not a summary of what the name suggests.
- Live inbox provisioning is not configured on this deployment.
packages/domain/src/platform-inboxes.ts:38 - Provider inbox creation could not be confirmed. The address stays reserved, the inbox stays paused, and the message asks for support contact before a retry.
packages/domain/src/platform-inboxes.ts:181 - An inbound retrieval failed with a retryable provider error.
packages/domain/src/services.ts:2638 - Provider attachment metadata is missing an id for at least one attachment.
packages/domain/src/services.ts:2698 - Downloading inbound attachment content from the provider failed.
packages/domain/src/services.ts:2702
How to fix it
- Retry with backoff for the inbound and attachment cases. These carry retryable: true and are genuinely transient.
- Do not retry a paused inbox provisioning. Contact support with the request id from the response; the address is already reserved and retrying can only add ambiguity.
- Keep the request id. Every response carries x-request-id and it is the fastest way to have one specific attempt looked at.
- Distinguish this from temporarily_unavailable. This code points at the mail provider; the other points at this service or its own dependencies.
Why it works this way
Never labelling an uncertain provider outcome as a failure is the rule this follows. A timeout is not proof that nothing happened, so the system records uncertainty and holds its reservations rather than rolling back and risking a duplicate.
Messages you will see
The message field is written for a human reading a log and is not a contract
value. Branch on code instead. These are the exact strings this code is sent
with today, listed so that a search for one of them lands here.
Where it appears
These are the documented surfaces that raise it. The REST base is https://api.emailforagents.ai/v1, and the remote MCP endpoint is https://mcp.emailforagents.ai/mcp.
POST /projects/{project_id}/inboxesGET /projects/{project_id}/inboxes/{inbox_id}/messages
The response
Read request_id off the body or the x-request-id header before
doing anything else. It is the only handle on one specific attempt, and for a 503 it is
the only handle at all, because the underlying detail stays server-side.
HTTP/1.1 503
content-type: application/json
x-request-id: req_...
{
"error": {
"code": "provider_unavailable",
"message": "Live inbox provisioning is not configured.",
"request_id": "req_...",
"retryable": true
}
}
Verified against packages/domain/src/platform-inboxes.ts:38. The status comes from ERROR_STATUS in packages/contracts/src/errors.ts, which is the one
place a code is mapped to a status.