The issue I think is to do with there being no unique boundaries being set in the –add footer section and MIME can not differentiate between the different content in the email from the previous boundary.
rspamd.local.lua (Original Code)
-- add footer
local out = {}
local rewrite = lua_mime.add_text_footer(task, footer.html, footer.plain) or {}
local seen_cte
local newline_s = newline(task)
local function rewrite_ct_cb(name, hdr)
if rewrite.need_rewrite_ct then
if name:lower() == 'content-type' then
local nct = string.format('%s: %s/%s; charset=utf-8',
'Content-Type', rewrite.new_ct.type, rewrite.new_ct.subtype)
out[#out + 1] = nct
-- update Content-Type header
task:set_milter_reply({
remove_headers = {['Content-Type'] = 0},
})
task:set_milter_reply({
add_headers = {['Content-Type'] = string.format('%s/%s; charset=utf-8', rewrite.new_ct.type, rewrite.new_ct.subtype)}
})
return
elseif name:lower() == 'content-transfer-encoding' then
out[#out + 1] = string.format('%s: %s',
'Content-Transfer-Encoding', 'quoted-printable')
-- update Content-Transfer-Encoding header
task:set_milter_reply({
remove_headers = {['Content-Transfer-Encoding'] = 0},
})
task:set_milter_reply({
add_headers = {['Content-Transfer-Encoding'] = 'quoted-printable'}
})
seen_cte = true
return
end
end
out[#out + 1] = hdr.raw:gsub('\r?\n?$', '')
end
rspamd.local.lua (New changes)
-- add footer
local out = {}
local rewrite = lua_mime.add_text_footer(task, footer.html, footer.plain) or {}
local seen_cte
local newline_s = newline(task)
local function rewrite_ct_cb(name, hdr)
if rewrite.need_rewrite_ct then
if name:lower() == 'content-type' then
local nct
if rewrite.new_ct.boundary then
nct = string.format('%s: %s/%s; charset=utf-8; boundary="%s"',
'Content-Type', rewrite.new_ct.type, rewrite.new_ct.subtype, rewrite.new_ct.boundary)
else
nct = string.format('%s: %s/%s; charset=utf-8',
'Content-Type', rewrite.new_ct.type, rewrite.new_ct.subtype)
end
out[#out + 1] = nct
-- update Content-Type header
task:set_milter_reply({
remove_headers = {['Content-Type'] = 0},
})
-- Pass only the value part without 'Content-Type: ' prefix
task:set_milter_reply({
add_headers = {['Content-Type'] = nct:sub(#'Content-Type: ' + 1)}
})
return
elseif name:lower() == 'content-transfer-encoding' then
out[#out + 1] = string.format('%s: %s',
'Content-Transfer-Encoding', 'quoted-printable')
-- update Content-Transfer-Encoding header
task:set_milter_reply({
remove_headers = {['Content-Transfer-Encoding'] = 0},
})
task:set_milter_reply({
add_headers = {['Content-Transfer-Encoding'] = 'quoted-printable'}
})
seen_cte = true
return
end
end
out[#out + 1] = hdr.raw:gsub('\r?\n?$', '')
end
When you add or change the footer (or any MIME part), you need to update the MIME boundaries properly throughout the message. If the boundaries remain the same as before, the email client gets confused because it relies on those unique boundary strings to know where each part starts and ends.
If you add a footer but don’t update the boundaries, the client may think the footer is still part of a previous section or completely miss it.
Properly generating new unique boundary strings when modifying the MIME structure ensures the footer (and any other parts) are clearly separated and correctly parsed.
In other words, updating boundaries is crucial to keep the MIME message structure consistent and prevent the footer (or other new parts) from being “stuck” or broken inside the email.
Here is an example email I sent with the new changes with set out unique boundaries to keep MIME content happy. …
**Content-Type: multipart/mixed; boundary="------------UeUleGTDieNxCT8rWJNek6yY"**
Message-ID: <3f1fe018-65f1-4990-a022-a4775f04b88e@piperweb.co.uk>
Date: Fri, 8 Aug 2025 14:29:35 +0100
MIME-Version: 1.0
User-Agent: Thunderbird Daily
Content-Language: en-US
To: Shane <example.com@gmail.com>
From: Shane <shane@example.com>
Subject: Testing Boundaries
X-Last-TLS-Session-Version: TLSv1.3
**--------------UeUleGTDieNxCT8rWJNek6yY
Content-Type: multipart/alternative; boundary="------------dXNNbxrK7puPgSeX8Np9e0ex"**
**--------------dXNNbxrK7puPgSeX8Np9e0ex
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: 7bit**
Hello I am testing boundaries
Regards,
Shane
© 2024 example.com. All Rights Reserved.
All emails are secured with TLS encryption and scanned for viruses to ensure safe communication.
To unsubscribe from receiving emails from us, please send an email to: unsubscribe@example.com
****--------------dXNNbxrK7puPgSeX8Np9e0ex**
Content-Type: text/html; charset=utf-8
Content-Transfer-Encoding: quoted-printable**
<!DOCTYPE html>
<html>
<head>
<meta http-equiv=3D"content-type" content=3D"text/html; charset=3DUTF-8=
">
</head>
<body>
<p><font face=3D"Helvetica, Arial, sans-serif">Hello I am testing
boundaries</font></p>
<p><font face=3D"Helvetica, Arial, sans-serif">Regards,</font></p>
<p><font face=3D"Helvetica, Arial, sans-serif">Shane</font></p>
<p><font face=3D"Helvetica, Arial, sans-serif">=C2=A0 =C2=A0=C2=A0</fon=
t></p>
</body>
</html>
<!DOCTYPE html>
<html lang=3D"en">
<head>
<meta charset=3D"UTF-8" />
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3DUTF-8" =
/>
<meta name=3D"viewport" content=3D"width=3Ddevice-width, initial-scale=3D=
1.0" />
<title>example.com Email</title>
</head>
<body style=3D"margin:0;padding:0;font-family:Arial,sans-serif;background-c=
olor:#ffffff;color:#333;">
<!-- Footer -->
<footer style=3D"background-color:#f4f4f4;padding:15px 20px;
display:flex;align-items:center;font-family:Arial,sans-serif;
font-size:12px;color:#333;">
<div style=3D"margin-right:15px;">
<img src=3D"https://example.com/web/image/2823-1f4faa3a/piplogo.pn=
g"
alt=3D"example Logo" style=3D"width:100px;height:100px;" />
</div>
<div style=3D"flex-grow:1;">
<p style=3D"margin:0;"> </p>
<p style=3D"margin:0;">=C2=A9 2025 . All Rights Reserved.</p>
<p style=3D"margin:0;">All emails are secured with TLS encryption and=
scanned for viruses
to ensure safe communication.</p>
<p style=3D"margin:0;">If you no longer wish to receive emails from u=
s, you can
<a href=3D"mailto:unsubscribe@example.com" style=3D"color:#333;
text-decoration:underline;">unsubscribe</a>.
</p>
</div>
</footer>
</body>
</html>
**--------------dXNNbxrK7puPgSeX8Np9e0ex--
--------------UeUleGTDieNxCT8rWJNek6yY**
**Content-Type: image/jpeg; name="**714358-3840x2160-desktop-4k-la-digue-seychelles-background-image-scaled.jpg"
**Content-Disposition: attachment; filename="**714358-3840x2160-desktop-4k-la-digue-seychelles-**background-image-scaled.jpg"
Content-Transfer-Encoding: base64**
**--------------UeUleGTDieNxCT8rWJNek6yY--**