## TL;DR
A body hash mismatch means the body that arrived is not the body that was signed. On invoice flows the culprit is normally something between the signer and the internet: a billing app that regenerates the PDF after signing, a gateway adding a disclaimer, or a system converting HTML or line endings. Sign as late as possible in the chain, after every transformation, and check that nothing downstream rewrites the message.

```text
dkim body hash mismatch error on outbound invoices
```

## Use this when
- Receivers report bh= mismatch or dkim=fail only for invoices or statements.
- The same domain signs newsletters and password resets successfully.

## Not for this skill when
- All outbound mail fails DKIM. That points at the key, selector or signer itself.
- The signature header is missing entirely on invoices. That is an unsigned stream, not a hash mismatch.

## Steps
1. Capture an invoice message at the signer and again at a receiving mailbox and compare body bytes and MIME structure. Verify: the point where the body changes is located.
2. Look specifically for disclaimer insertion, PDF regeneration, charset conversion and quoted-printable re-encoding after signing. Verify: the altering component is named.
3. Move signing to the last outbound gateway so it happens after disclaimers and attachments are final, or stop the downstream rewrite for this stream. Verify: nothing after the signer touches the body.
4. Confirm the signer uses relaxed body canonicalisation for this stream if minor whitespace handling differs across hops. Verify: the canonicalisation values in the signature are as intended.
5. Send a fresh invoice through the full path. Verify: the receiver shows dkim=pass with no body hash error.

## Variant phrasings
### dkim bh mismatch body hash did not verify
The verbatim hash variant receivers report.
### dkim fails only on invoices disclaimer after signing
The stream-specific variant.

Compatibility: RFC 6376 body hash and canonicalisation, Exchange and Postfix outbound gateways, common billing platforms.

## Why it happens
DKIM signs a hash, not the idea of the message. Invoice pipelines are prone to post-signing edits because documents are rendered, stamped, archived and re-attached by separate components, each of which can silently change the bytes.

## Edge cases / pitfalls
- An empty-body versus single-newline difference alone can change the hash. Test with the real invoice generator, not a hand-typed message.
- Signing with l= body length is fragile and widely discouraged. Avoid it as a workaround.
- If a third party sends invoices for you, its signer must be authoritative. Double signing by two systems invites exactly this fault.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_2W2pr74vkMm8eVu49LJh9Q
