Skip to main content

Troubleshooting: fax sends fail or never arrive

Fax failures split into four classes, and the fix is different for each: the API refused the send (content/destination reject), the carrier failed the transmission (passthrough failure with a diagnostic), a transient gateway error sits between your client and the carrier, or the record terminal’d sent but the recipient never received pages. This page walks all four, with the billing rule that decides what each one costs you. If the row is stuck pre-queue (queued, pending), work the queue-side troubleshooting page instead. This page assumes the send was dispatched.

Symptom map

Three surfaces read the same fax row: the Delivery Log filtered by channel (/messages/delivery-log?channel=fax), the authoritative row on GET /api/v1/messages/:id, and the message.failed webhook payload with channel: "fax". Match the symptom to its class first — the same status word points at different layers.

Cause → fix

Work the class you matched above. Each fix is a one-shot check before you resend — fax is single-attempt from the queue side (the worker only re-dispatches while the row is queued), so a terminal failed row is re-sent as a new message.

What not to do

  • Do not retry a destination reject (busy, no answer, no fax tone) in a loop. These are deterministic — the same send fails the same way until the line frees or the recipient confirms the number. One sensible re-send after the line clears, not a retry loop.
  • Do not resend the same payload against poor_line_quality without lowering quality. The handshake length is the variable; unchanged, the re-send fails the same way.
  • Do not count a sent-hold as delivered. Carriers ack delivered at different points; treat sent as carrier-completed and only delivered as end-station-confirmed.
  • Do not bypass retry_after on a 5xx. A single retry is the shape defined here; repeated immediate retries against a provider 5xx amplify the queue rather than recover it.

Billing note

Fax is on-success-charge — your wallet deducts only when the carrier confirms a successful transmission. Every failure class above (content reject, destination reject, gateway 5xx, line failure, delivered-never-received) is not billed — this holds for both the initial send and any sensible re-send. The provider-side idempotency key (orbit-fax:<message-id>) also keeps a legitimate same-message retry from double-charging. Charged rows appear on your billing overview only after a successful transmission.

Escalation bundle

Open a support ticket when one of these holds:
  • A 502 MESSAGE_SEND_FAILED persists after one retry and your tenant fax_connection_id resolves cleanly.
  • A destination reports fax-reachable and the carrier returns handshake_rejected on every attempt.
  • A row held at sent for several hours with no delivered or failed terminal.
Include the four fields support needs to pull the provider trace without a back-and-forth:
  1. Tenant ID (dashboard → Settings → Organization; API → GET /api/v1/me returns it as organizationId)
  2. Re-enquire request_id — the send POST’s meta.request_id (returned in the error envelope for the 4xx/5xx classes, or in the successful enqueue response for the terminal failed class)
  3. Destination number in E.164
  4. Fax/Message ID — msg_… from the row (On route GET /api/v1/fax/:id, the provider-side external_id attaches after dispatch — include both where present)
For a held-at-sent row, run the self-serve route-trace timeline (GET /api/v1/messages/:id/trace) first — the failure stage (validation / submission / carrier) narrows which class above to escalate.

See also

  • Fax channel page — send fields, errors, limits, and the status lifecycle this page decodes
  • Outbound fax workflow — the complete send-side walkthrough: billing timing, receipts, and document guidance
  • Delivery log — the dashboard surface behind the channel=fax filter
  • Message undelivered or failed — the channel-agnostic failure decoder (the classifier metadata.classified_error_code)
  • Error codes — the JSON error envelope and the MESSAGE_SEND_FAILED / validation code catalog
  • Webhook events — the message.delivered / message.failed payloads (channel: "fax" events arrive on the channel-agnostic surface)