Skip to content

Outbound Relay and Providers

Ra's al Ghul edited this page Aug 9, 2026 · 1 revision

Outbound Relay and Providers

Trusted SMTP listener

Mailbridge can listen on SMTP_RELAY_PORT (default 2525) for trusted local systems. It is disabled by default and does not provide username/password authentication. Access control is based on source CIDRs plus TLS policy.

Before accepting message submission, the relay:

  1. Normalizes IPv4-mapped IPv6 addresses.
  2. Checks the connection against SMTP_RELAY_ALLOWED_CIDRS using Node's IP block list.
  3. Requires STARTTLS when SMTP_RELAY_REQUIRE_TLS=true.
  4. Rejects DATA beyond SMTP_RELAY_MAX_MESSAGE_BYTES with SMTP 552 without retaining excess bytes.

Default allowlist:

SMTP_RELAY_ALLOWED_CIDRS=127.0.0.1/32,::1/128

Never expose this listener to the public internet. Docker Desktop clients may appear from 192.168.65.0/24; Linux bridge addresses differ. Add only the exact source network observed in logs.

Message preparation

Mailbridge parses the submitted RFC 822 message, preserves text, HTML, supported custom X-* headers, and attachments, then builds the provider-specific request. Optional relay headers identify the provider and processing hop.

Each recipient is audited separately. If a temporary provider failure occurs, each recipient is placed into the encrypted retry queue. Permanent configuration or provider rejections return SMTP 550.

SendGrid

RELAY_UPSTREAM_PROVIDER=sendgrid
RELAY_API_KEY=replace_with_sendgrid_key
RELAY_FROM_FALLBACK=postmaster@example.com

Mailbridge sends a JSON request to SendGrid's v3 Mail Send API. HTTP 429 and 5xx responses remain retryable; other 4xx responses are permanent.

Resend

RELAY_UPSTREAM_PROVIDER=resend
RELAY_API_KEY=replace_with_resend_key
RESEND_BASE_URL=https://api.resend.com
RELAY_FROM_FALLBACK=postmaster@example.com

Text, HTML, custom headers, and base64 attachments are sent to the Resend Emails API.

Mailgun

RELAY_UPSTREAM_PROVIDER=mailgun
RELAY_API_KEY=replace_with_mailgun_key
MAILGUN_DOMAIN=mg.example.com
MAILGUN_BASE_URL=https://api.mailgun.net

Mailbridge submits a complete MIME message to Mailgun's messages.mime endpoint, preserving the message structure.

Cloudflare Email Service

RELAY_UPSTREAM_PROVIDER=cloudflare
CLOUDFLARE_SEND_WORKER_URL=https://mailbridge-worker.example.workers.dev/api/send/email
CLOUDFLARE_SEND_WEBHOOK_SECRET=replace_with_dedicated_outbound_secret

Mailbridge POSTs the prepared message to the Worker's /api/send/email route. The Worker validates CLOUDFLARE_SEND_WEBHOOK_SECRET when configured, falls back to WEBHOOK_SECRET only for compatibility, and calls env.EMAIL.send(...).

Use a distinct outbound secret. Upload it with:

npx wrangler secret put CLOUDFLARE_SEND_WEBHOOK_SECRET

Rate and daily-limit errors become HTTP 429; internal delivery failures become 502; invalid requests are permanent 4xx failures.

Retry classification

  • Explicit provider permanent=true always wins.
  • Explicit permanent=false keeps failures retryable, including provider 5xx responses.
  • HTTP 429 is temporary.
  • Provider 4xx responses other than 429 are normally permanent.
  • SMTP 5xx responses without an explicit override are permanent.
  • Network errors and timeouts are temporary.

Clone this wiki locally