Troubleshooting: inbound email never routes
Inbound email to your parse domain runs three surfaces in parallel — a webhook forward to your endpoint, an inbox conversation, and (optionally) an email Flow. When you see none of them, work this page top to bottom. It isolates DNS, route matching, normalization, and trigger issues one at a time, so the escalation you open carries exactly the inputs Support needs. The full setup walkthrough lives in inbound email and SMS routing. This page assumes that setup exists and something is misbehaving.1. The inbound parse pipeline, in order
Every inbound email passes through these stages, and each stage is a place the pipeline can stop:- DNS → MX records. The receiving domain’s MX records point at Orbit’s ingress hostname (shown in Email → Inbound routes → Add route). Until MX resolves, no mail arrives at all.
- Route match. The SMTP envelope recipient is matched against your
registered inbound routes — exact address, catch-all
(
*@domain), or local-part — then theToandCcheaders. No match, no parse. - Normalization. The message is parsed into the normalized payload
(
from,toAddress,matchedRecipient,subject,text,html,attachmentsmetadata,headersincludingmessage-id). - Fan-out. The normalized message is forwarded to your
destinationUrlas a signedPOSTand simultaneously opens (or threads onto) an inbox conversation. Signature verification and a 2xx response are required for the forward to count as delivered. - (Optional) Flow trigger. An email-channel Flow can react to the inbound event — compose a reply through email, or fan out to another channel. Inbound email routes themselves have no built-in reply path.
2. Symptom → where to look
3. Diagnostic checklist
Work each item in order — collect the output as you go; it becomes your escalation payload.- DNS.
dig MX inbound.your-domain.com(or your DNS provider’s record viewer) — confirm the MX record points at the ingress hostname the dashboard displayed when you created the route. - Route shape.
GET /email/inbound-routes— confirm a route exists and itsrecipientPatterncovers the exact address being written to, in whichever syntax (exact, catch-all, local-part) you registered. Checkactive: trueandfailureCount: 0. - Normalized payload. From an earlier working message (or the
guide’s example): does the payload
carry
textorhtml, and aheaders.message-id? A body-less message is valid but can break downstream matchers. Attachment bytes never appear here — only metadata — unless you setincludeRawMime: trueon the route. - Signature. Your endpoint must verify the
X-Orbit-Signatureheader (sha256=<hex>, HMAC over the raw body, keyed by the route’ssigningSecret) and return 2xx. Only 2xx counts; redirects are not followed. - Flow trigger. If you expected a Flow: open it, confirm it triggers on the inbound email event, and confirm the trigger is enabled and published. The flow executions page covers trigger-side failure in more depth.
4. Escalate with these
Open a ticket when every item above is clean and inbound mail still never lands. Include all four:- The parse domain (for example
inbound.your-domain.com). - The route id from
GET /email/inbound-routes(theeinr_…id). - One sample
headers.message-idfrom a message that should have routed (the RFC 5322 Message-ID header). - Your tenant ID — in the dashboard under Settings → Organization,
and returned by the
GET /api/v1/meresponse asorganizationId.
See also
- Inbound email and SMS routing — full setup walkthrough, payload shape, match-rule reference
- Flows overview — auto-reply and richer orchestration
- Flow executions failed — trigger-side failures in depth
- Email operational notes — attachment and MIME handling on the outbound side
- Webhook events reference — event types, payload fields, endpoint scoping