ADR / 007

Treat uncertain integration outcomes as unknown, not failed

A timeout says nothing about whether the receiver committed. Model ‘unknown’ as its own state, resolve it by request key, and only then retry or fail.

Reference pattern

Independently created. Contains no employer or client implementation detail, internal names or figures.

01Context

A CRM sends customer-creation and order requests to an ERP through an integration layer. Under load, some calls time out after the ERP has already committed. The integration marks them failed; users or automated retries resend, and duplicate legal customers and orders appear. Other timeouts really are failures—and to the caller the two look identical.

02Decision drivers

  1. D01

    A duplicate legal customer is expensive to unwind

  2. D02

    Users need an honest status while the outcome is uncertain

  3. D03

    The receiver can be queried by an external request key

  4. D04

    Transient faults still need retries

03Options considered

Rejected

Treat a timeout as a failure and retry

Receivers that are idempotent by design

Cost: A duplicate whenever the receiver had committed
Rejected

Treat a timeout as a success

Nothing that matters

Cost: Silent gaps: orders against customers that do not exist
Selected

An Unknown state, resolved by request key

Receivers that are not, or not fully, idempotent

Cost: Needs a queryable request key, a resolution job and an owner

04Decision

Every outbound request carries an idempotency key scoped to the business request and a correlation ID. A timeout or lost response moves the request to Unknown—not Failed. Before any retry, the integration layer looks the request up at the receiver by its key: found means confirm; not found means retry with the same key; still unresolved after the retry budget means escalate to a named owner. Users see “outcome being confirmed”, never an invitation to press the button again.

05Consequences

  • Unknown becomes a monitored business state with an age and an owner.
  • Retries are safe: the same key cannot create twice.
  • Reconciliation closes the Unknowns that the resolution job cannot.
  • The receiver must support lookup by external request key—or the integration layer keeps a ledger of what it sent.

06Revisit when

01

The receiver guarantees idempotent creation by key.

02

The operation becomes read-only or naturally idempotent.