Prerequisites
Describe the issue
Environment
- Roundcube 1.7.1 (upgraded from 1.6.15)
- Submission to a local Postfix; DKIM signing via Rspamd milter at submission time
Description
After upgrading 1.6.15 → 1.7.1, HTML emails containing a long HTML signature fail DKIM at the recipient with body hash did not verify. The same signature/content composed in 1.6.15 passes DKIM fine. Downgrading back to 1.6.15 makes the problem disappear, so this looks like a regression in how 1.7.x serializes the message body.
Root cause (analyzed from the raw message)
In 1.7.1 the text/html part is emitted as Content-Transfer-Encoding: 8bit with the body on a single physical line exceeding 998 octets (in our case ~2000+ octets — the whole signature paragraph with inline <img>/links on one line).
RFC 5322 §2.1.1 requires body lines to be ≤ 998 octets. Because 1.7.1 emits longer lines, any MTA in the path that enforces the line-length limit wraps the line (inserts CRLF) — and since this happens after DKIM signing, the body hash no longer matches → DKIM fails. The inserted fold survives relaxed body canonicalization (the whitespace at the fold point is not stripped), so the failure is deterministic, not transient.
1.6.15 does not produce >998-octet body lines with identical content, hence it works.
Steps to reproduce
- Roundcube 1.7.1, HTML compose, set an HTML signature long enough that the rendered HTML body contains a single line > 998 octets (e.g. a signature with several inline images/links).
- Send to any DKIM-verifying recipient (e.g. Gmail).
- Recipient reports
dkim=... (body hash did not verify).
- Compose the same content in 1.6.15 → passes.
Workaround (confirmed working on 1.7.1)
$config['force_7bit'] = true;
This forces quoted-printable, which soft-wraps at 76 columns, so no body line exceeds 998 octets and nothing gets re-wrapped after signing. After enabling it, the text/html part is Content-Transfer-Encoding: quoted-printable and DKIM passes.
Question for maintainers
Did HTML body line-wrapping/encoding change between 1.6 and 1.7? Emitting HTML body lines > 998 octets in 8bit mode is non-conformant (RFC 5322 §2.1.1) and breaks DKIM in any normal mail path that enforces the SMTP line-length limit. Should long body lines be wrapped (or QP-encoded) by default even in 8bit mode?
I can share the exact signature / raw message privately (not public) on request.
What browser(s) are you seeing the problem on?
No response
What version of PHP are you using?
8.5
What version of Roundcube are you using?
1.17.1
JavaScript errors
No response
PHP errors
No response
Prerequisites
Describe the issue
Environment
Description
After upgrading 1.6.15 → 1.7.1, HTML emails containing a long HTML signature fail DKIM at the recipient with
body hash did not verify. The same signature/content composed in 1.6.15 passes DKIM fine. Downgrading back to 1.6.15 makes the problem disappear, so this looks like a regression in how 1.7.x serializes the message body.Root cause (analyzed from the raw message)
In 1.7.1 the
text/htmlpart is emitted asContent-Transfer-Encoding: 8bitwith the body on a single physical line exceeding 998 octets (in our case ~2000+ octets — the whole signature paragraph with inline<img>/links on one line).RFC 5322 §2.1.1 requires body lines to be ≤ 998 octets. Because 1.7.1 emits longer lines, any MTA in the path that enforces the line-length limit wraps the line (inserts
CRLF) — and since this happens after DKIM signing, the body hash no longer matches → DKIM fails. The inserted fold survivesrelaxedbody canonicalization (the whitespace at the fold point is not stripped), so the failure is deterministic, not transient.1.6.15 does not produce >998-octet body lines with identical content, hence it works.
Steps to reproduce
dkim=... (body hash did not verify).Workaround (confirmed working on 1.7.1)
This forces quoted-printable, which soft-wraps at 76 columns, so no body line exceeds 998 octets and nothing gets re-wrapped after signing. After enabling it, the
text/htmlpart isContent-Transfer-Encoding: quoted-printableand DKIM passes.Question for maintainers
Did HTML body line-wrapping/encoding change between 1.6 and 1.7? Emitting HTML body lines > 998 octets in 8bit mode is non-conformant (RFC 5322 §2.1.1) and breaks DKIM in any normal mail path that enforces the SMTP line-length limit. Should long body lines be wrapped (or QP-encoded) by default even in 8bit mode?
I can share the exact signature / raw message privately (not public) on request.
What browser(s) are you seeing the problem on?
No response
What version of PHP are you using?
8.5
What version of Roundcube are you using?
1.17.1
JavaScript errors
No response
PHP errors
No response