A line-ending problem is a byte-level problem. Copying a message into an editor, seeing the same lines and concluding that nothing changed is not a reliable DKIM investigation. Preserve the original representation and identify whether conversion occurred before signing, in transit or only during evidence collection.
Establish the expected form
Internet mail uses CRLF line separators. RFC 6376 §5.3 requires a signer to convert local bare CR or LF conventions to the SMTP-standard CRLF sequence before signing. The conversion should apply to the transmitted message, not merely to a private copy passed to the signing algorithm. Signing one representation and transmitting another invites disagreement at verification.
Canonicalization has narrower rules than general text normalization. Simple body canonicalization ignores trailing empty lines and supplies the required final CRLF. Relaxed body canonicalization also removes end-of-line whitespace and compresses runs of spaces or tabs within a line. It does not generally erase meaningful line breaks or join wrapped text. The header and body algorithms can differ, so read both parts of c rather than assuming a single mode.
Protect the evidence first
Collect raw message files from the signer and receiver using methods whose transformations you understand. Keep read-only originals and hashes of those files. In a working copy, examine CRLF, bare LF and bare CR counts using a byte-aware tool. A text viewer's display is not sufficient: many viewers render each form as a line break.
Ask how the sample was obtained. An archive, shell pipeline or source-control setting may normalize endings after delivery. A difference in exported files does not establish that the SMTP message itself changed. Where possible, compare independent captures at the same boundary and retain the export procedure with the evidence.
Use a small controlled case
Illustrative input: a body consists of alpha, a CRLF, beta, and a final CRLF. Adding an empty CRLF-only line at the end is normalized away by the standard body algorithms. Replacing the line break between alpha and beta with a space changes the content and is not the same operation. Adding spaces at the end of the alpha line differs under simple body canonicalization but is normalized by relaxed body canonicalization.
These examples explain the rules; they are not a substitute for verifying a complete signature. A valid body hash is only one part of DKIM verification. Header selection, public-key retrieval and the cryptographic signature must also succeed.
Find and correct the responsible stage
If the signer receives LF-only local data, inspect the serialization stage before signing. If signer output is correct but a later raw capture differs, investigate that hop's conversion or rebuilding behavior. If only your exported evidence differs, repair the capture method rather than modifying production DNS or keys.
Make a narrowly scoped change that ensures the signer and transmitted message use the same normalized representation. Do not invent a custom verifier that accepts arbitrary line transformations to make the sample pass. Such a verifier would no longer be testing the published DKIM rules.
Verify beyond one message
After the change, send a small suite covering plain text, blank trailing lines, HTML and attachments. Record the selected canonicalization, the collected raw-file hashes and the trusted receiver's verification result. Keep the expected output representation as a regression fixture. A useful resolution identifies the responsible conversion and demonstrates that new messages reach the receiver in the intended form.
Keep byte counts separate from conclusions
For the synthetic body alpha<CRLF>beta<CRLF>, the network-form body is 13 octets: five letters, two separator octets, four letters and two final separator octets. An LF-only export of the same visible lines is 11 octets. That count difference is a reason to investigate collection or serialization, not proof that the transmitted mail was damaged. Keep the original files and collection methods, then compare with a trusted capture at the relevant boundary. The bracketed CRLF label represents bytes, not literal text.