Send Failed
ERR-P01-MAIL-4001 - Send Failed
Section titled “ERR-P01-MAIL-4001 - Send Failed”Summary
Section titled “Summary”An outbound provider (Cloudflare Mail / Resend / SES / Google) returned an error while dispatching the message.
When this is raised
Section titled “When this is raised”POST /mailsaccepted the body and resolved a From address, butsendMail(...)threw while handing the message to the configured outbound provider chain.- The audit row has already been persisted with
deliveryStatus = 'failed'before the error is re-coded, so the attempt is recorded server-side. - The underlying provider message is surfaced verbatim as the envelope
message, so it can name the failing provider or reason. - This is the bearer
POST /mailssurface. The/_internal/notifyroute takes a different shape: it always returns202and records the outcome in the log row’sstatus, so it does not emit this code.
What to do
Section titled “What to do”- Treat
502as retryable. Retry once after a short backoff with jitter; many provider errors (timeouts, transient 5xx) clear on retry. - If it persists, inspect the
messagefor the provider’s reason and check the operator’s outbound-provider credentials andmail.outbound.priorityconfiguration. - A persistent failure across all configured providers indicates a provider-side or credential problem, not a request bug.
Server-side cause
Section titled “Server-side cause”- Raised by:
packages/mail/src/router/index.ts- thePOST /mailshandler, in thecatcharoundsendMail(...):throw MAIL.sendFailed(err instanceof Error ? err.message : String(err)). - Guard: any rejection from
sendMail/ the provider chain inapps/mail/src/outbound/*(cloudflare,resend,ses,google,fallback); the row is persisted asfailedfirst, then a502is surfaced.
Example response
Section titled “Example response”{ "type": "https://citizenry.id/errors/ERR-P01-MAIL-4001", "title": "Bad Gateway", "status": 502, "code": "ERR-P01-MAIL-4001", "message": "resend: 422 domain is not verified", "method": "POST", "instance": "/mails", "request_url": "https://mail.citizenry.id/mails", "timestamp": "2026-05-17T07:00:00.000Z"}Related codes
Section titled “Related codes”ERR-P01-MAIL-0429- a provider/limiter rate-limit signal, the other external-dependency failure (reserved).ERR-P01-MAIL-0503- the mail backend unavailable as a whole (vs. a single send failing).
Changelog
Section titled “Changelog”- 0.1.0 - introduced.