> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting: inbound email never routes

> Work through why inbound mail to your parse domain never opens a conversation, why a match rule did not fire, why a Flow auto-reply looped, or why bounces and unsubscribes broke the parse — and what to collect before you escalate.

# 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](/guides/inbound-email-parse). 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:

1. **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.
2. **Route match.** The SMTP envelope recipient is matched against your
   registered inbound routes — exact address, catch-all
   (`*@domain`), or local-part — then the `To` and `Cc` headers. No
   match, no parse.
3. **Normalization.** The message is parsed into the normalized payload
   (`from`, `toAddress`, `matchedRecipient`, `subject`, `text`, `html`,
   `attachments` metadata, `headers` including `message-id`).
4. **Fan-out.** The normalized message is forwarded to your
   `destinationUrl` as a signed `POST` and simultaneously opens (or
   threads onto) an inbox conversation. Signature verification and a
   2xx response are required for the forward to count as delivered.
5. **(Optional) Flow trigger.** An email-channel
   [Flow](/flows/overview) 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

| Symptom                                      | First check                                                                                                                                                     | Second check                                                                                                    |
| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| No conversation, no webhook, no trace        | MX records on the parse domain resolve to Orbit's ingress host                                                                                                  | A route exists whose `recipientPattern` covers the actual recipient (exact, catch-all, or local-part syntax)    |
| Route exists and DNS is fine, still nothing  | The address being written to actually matches the pattern — BCC/aliased mail matches envelope first, but a sender addressing a *different* domain gets no match | Route `active` flag — a disabled route matches nothing                                                          |
| Webhook forward fails, conversation opens    | Your endpoint returned a non-2xx, or rejected the signature                                                                                                     | `failureCount` / `lastFailureAt` on the route via `GET /email/inbound-routes`                                   |
| Conversation opens but no Flow trigger       | The Flow listens on the inbound email event and its trigger is published/enabled                                                                                | `text`/`html` are both `null` — an empty-body message can slip past trigger conditions that expect body content |
| Flow auto-reply looped                       | Your Flow's "send email" step targets an address back at the parse domain — the loop closes on itself                                                           | Add a reply-to / subject guard in the Flow, or use the inbox reply surface instead of a no-guard outbound send  |
| Bounces and unsubscribes swallowed the parse | A compliance-suppressed recipient on the outbound side — suppressions apply at send, and inbound parse never unsubscribes anyone                                | Non-2xx webhook responses recorded as forward failures, not parse failures                                      |

## 3. Diagnostic checklist

Work each item in order — collect the output as you go; it becomes your
escalation payload.

1. **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.
2. **Route shape.** `GET /email/inbound-routes` — confirm a route
   exists and its `recipientPattern` covers the exact address being
   written to, in whichever syntax (exact, catch-all, local-part) you
   registered. Check `active: true` and `failureCount: 0`.
3. **Normalized payload.** From an earlier working message (or the
   [guide's example](/guides/inbound-email-parse)): does the payload
   carry `text` or `html`, and a `headers.message-id`? A body-less
   message is valid but can break downstream matchers. Attachment bytes
   never appear here — only metadata — unless you set
   `includeRawMime: true` on the route.
4. **Signature.** Your endpoint must verify the `X-Orbit-Signature`
   header (`sha256=<hex>`, HMAC over the raw body, keyed by the route's
   `signingSecret`) and return 2xx. Only 2xx counts; redirects are not
   followed.
5. **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](/troubleshooting/flow-executions-failed) 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` (the `einr_…` id).
* One sample **`headers.message-id`** from 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/me` response as `organizationId`.

With the domain, route id, and a concrete Message-ID, Support can tell
within one lookup whether the message reached ingress at all, and which
stage turned it away.

## See also

* [Inbound email and SMS routing](/guides/inbound-email-parse) — full
  setup walkthrough, payload shape, match-rule reference
* [Flows overview](/flows/overview) — auto-reply and richer orchestration
* [Flow executions failed](/troubleshooting/flow-executions-failed) —
  trigger-side failures in depth
* [Email operational notes](/guides/email-attachments) — attachment and
  MIME handling on the outbound side
* [Webhook events reference](/reference/webhook-events) — event types,
  payload fields, endpoint scoping
