Subj : mailsrvr: false 'DKIM body hash changed' error when a send fails mid-b To : GitLab issue in main/sbbs From : Rob Swindell Date : Sun Oct 04 2026 20:40:42 open https://gitlab.synchro.net/main/sbbs/-/work_items/1279 When an outbound SMTP delivery's connection drops partway through sending the message body, the mail server logs a misleading DKIM error: ``` 12:11:34 2332 SEND connecting to port 25 on mx1.emailn.de [178.63.251.174] 12:11:42 2332 SEND TLS Session started successfully 12:12:22 2332 SEND/TLS dbg 'WSAECONNABORTED: Connection was terminated due to a time-out or other failure' (-42) flushing data 12:12:22 2332 SEND/TLS !DKIM body hash changed between sign and send - message delivery aborted 12:12:22 2332 SEND !Delivery attempt #1 FAILED (mx1.emailn.de replied with: ``` A second occurrence on 2026-08-17 (plain SMTP, no TLS) shows the same sequence: `Connection aborted by peer on send`, then the DKIM error. Because it is logged at `LOG_ERR`, the error also lands in `data/error.log`. Nothing changed between signing and sending. The connection failed, and the DKIM verify pass then hashed a truncated body. ## Cause In `mailsrvr.cpp`: 1. During pass 2, `sockprintf()` feeds each line to the DKIM verify capture (`dkim_capture_line()`) *before* trying to transmit it. 2. In `sockmimetext()`'s body loop, the first failed `sockprintf()` exits the loop with `break`. The rest of the body and any attachments are skipped. 3. Execution still reaches `sockprintf(..., ".")` at the end of `sockmimetext()`. The verify capture sees the end-of-data terminator, finalizes a hash over the partial body, and sets `mismatch`. The caller then logs "DKIM body hash changed between sign and send". The "message delivery aborted" part is also misleading: the dropped connection had already ended the delivery. ## Suggested fix In the `sockmimetext()` body loop, replace `break` with `return lines;`. This follows the existing early `return 0` when the header-terminator send fails. After a failed send the session is unusable, so the terminator and attachment encoding can't reach the peer anyway. With this change: - The DKIM verify capture never sees `.`, so there's no false mismatch. - Attachments are no longer MIME-encoded into a dead socket. - `MSG_KILLFILE` attachments are left in place, which is correct because they weren't delivered. The POP3 RETR path, which shares `sockmimetext()`, gets the same early exit. ## Release notes DKIM signing (#215) was added after v3.21e, so this fix doesn't need an entry in `docs/v322_new.md`. _Authored by Claude (Claude Code), on behalf of @rswindell_ --- SBBSecho 3.38-Linux * Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705) .