MDN receipts
The MDN (Message Disposition Notification) is AS2’s proof of delivery: a
structured receipt carrying the disposition (processed, or an error)
and the Received-Content-MIC — a digest of what the receiver actually
got. When it matches the sender’s own digest, the loop is closed.
Requesting receipts (outbound)
[partnership.mdn]
request = true # ask for a receipt
signed_micalg = "sha-256" # ask for a SIGNED receipt with this digest
# async_url = "https://my.example/as2/mdn" # deliver asynchronously
- Synchronous (no
async_url): the receipt comes back on the same HTTP connection as the send. Simplest; use it unless payloads are large enough that partners time out generating receipts inline. - Asynchronous: the partner answers the POST immediately and later
delivers the receipt to your
async_url. as2d correlates it by Original-Message-ID, verifies the signature against the pinned partner certificate, checks the MIC, and journals the outcome. Receipts that fail authentication or match no pending message are rejected without consuming state.
Outbound sends and their receipt state live in the durable queue — a crash or restart between send and receipt loses nothing.
Serving receipt requests (inbound)
as2d honors what the partner’s Disposition-Notification-Options asks
for: signed receipts with any supported digest, unsigned receipts, sync
or async (async delivery goes through the durable retry queue, so an
unreachable partner URL is retried with backoff).
Receipt requests that cannot be honored are answered the way RFC 4130
requires — an explicit failed/Failure receipt rather than a silently
different one — for example a request for a signature protocol or digest
we do not support, or an async receipt request on a deployment whose
license does not include async MDNs.
Security guards on the receipt channel:
- A
Receipt-Delivery-OptionURL from an unknown partner is never honored (the error receipt goes back synchronously) — otherwise an unauthenticated request could aim durable, retried POSTs at any URL. - Only
http:/https:receipt URLs are ever delivered to.
When MICs don’t match
A MIC mismatch on an otherwise successful exchange almost always means the two sides disagree about what to digest, not that data was corrupted. Check, in order:
- Mirrored security attributes — see the onboarding gotcha in Partnerships: both sides must declare the same sign/encrypt/compress attributes or the headers-in-digest decision diverges.
- The counterpart’s known quirks — several products digest something slightly different in specific corners (documented per product in Working with specific products).
- The requested micalg — some products ignore the requested receipt digest and use their default or the signature digest; requesting the digest the partner will actually use makes reconciliation exact.
as2d journals mdn-mic-mismatch distinctly so these are visible and
alertable rather than silently logged.