>From the debugger, once X-Envelope-From was renamed to EnvelopeFrom in the >test email, the debugger printed the following:
> [...] dbg: message: using Return-Path header as EnvelopeFrom: 'omitted' > ... > [...] dbg: spf: EnvelopeFrom not found in first external Received header > [...] dbg: spf: found EnvelopeFrom 'omitted' from header > ... > [...] dbg: spf: using Mail::SPF for SPF checks > ... (*failure, see below*) By comparison, this is how it behaved with X-Envelope-From: > [...] dbg: message: X-Envelope-From header found after 1 or more Received > lines, cannot trust envelope-from > ... > [...] dbg: spf: EnvelopeFrom not found in first external Received header > [...] dbg: spf: EnvelopeFrom header not found > [...] dbg: spf: cannot get EnvelopeFrom, cannot use SPF by DNS > [...] dbg: spf: spf_welcomelist_from: no EnvelopeFrom available for > welcomelist check > [...] dbg: spf: def_spf_welcomelist_from: could not find usable envelope > sender So, - if X-EnvelopeFrom is explicit in the mail, SA ignores it and seeks for EnvelopeFrom. - if EnvelopeFrom is explicit in the mail, SA ignores it and seeks for Retrurn-Path. - if envelope_sender_header is defined as Return-Path or X-Envelope-From, SA ignores it anyway. On the failure, noted above, this is what happens. This is the Received-SPF header: Received-SPF: pass (server1.com: Sender is authorized to use '[email protected]' in 'mfrom' identity (mechanism 'include:cust-spf.exacttarget.com' matched)) receiver=me.com; identity=mailfrom; envelope-from="[email protected]"; helo=server2.com; client-ip=[IP] The debugger says > [...] dbg: spf: checking HELO (helo=server2.com, ip=[IP]) > [...] dbg: spf: query for [IP]/server2.com: result: none, comment: , text: No > applicable sender policy available > [...] dbg: spf: welcomelist_from_spf: [email protected] is not in user's > WELCOMELIST_FROM_SPF > [...] dbg: spf: def_welcomelist_from_spf: [email protected] is not in > DEF_WELCOMELIST_FROM_SPF So, the mail has a "Received-SPF: pass" header, but SA cannot retrieve the correct TXT RR. Notes: - From and Return-Path are different in the test email. - [email protected] above is the Return-Path, used in the welcomelist_from_spf rule. Sorry, it is a bit convoluted and I used the e-mail as study notes. I hope you followed through anyway. -- Otto On Friday, December 12th, 2025 at 9:55 PM, Otto Cooper <[email protected]> wrote: > And finally, according to the following reference, SA was not supposed to > ignore X-Envelope-From. > > > perldoc Mail::SpamAssassin::Plugin::SPF > > > welcomelist_from_spf [email protected] > > Previously whitelist_from_spf which will work interchangeably until > 4.1. > > Works similarly to welcomelist_from, except that in addition to > matching a sender address, a check against the domain's SPF record > must pass. The first parameter is an address to welcomelist, and the > second is a string to match the relay's rDNS. > > Just like welcomelist_from, multiple addresses per line, separated > by spaces, are OK. Multiple "welcomelist_from_spf" lines are also > OK. > > The headers checked for welcomelist_from_spf addresses are the same > headers used for SPF checks (Envelope-From, Return-Path, > X-Envelope-From, etc). > > Since this welcomelist requires an SPF check to be made, network > tests must be enabled. It is also required that your trust path be > correctly configured. See the section on "trusted_networks" for more > info on trust paths. > > e.g. > > welcomelist_from_spf [email protected] [email protected] > welcomelist_from_spf *@example.com > > > I am using Mail-SpamAssassin version 4.0.2 from OpenBSD, which is the same as > the cpan version. > > > > > On Friday, December 12th, 2025 at 9:44 PM, Otto Cooper [email protected] > wrote: > > > According to the following references, SA should use the Return-Path header > > instead of EnvelopeFrom, but is clearly not doing it. > > > > https://cwiki.apache.org/confluence/display/spamassassin/EnvelopeSenderInReceived > > > > > perldoc Mail::SpamAssassin::Conf > > > > envelope_sender_header Name-Of-Header > > > > SpamAssassin will attempt to discover the address used in the 'MAIL > > FROM:' phase of the SMTP transaction that delivered this message, if > > this data has been made available by the SMTP server. This is used > > in the "EnvelopeFrom" pseudo-header, and for various rules such as > > SPF checking. > > > > By default, various MTAs will use different headers, such as the > > following: > > > > X-Envelope-From > > Envelope-Sender > > X-Sender > > Return-Path > > > > SpamAssassin will attempt to use these, if some heuristics (such as > > the header placement in the message, or the absence of fetchmail > > signatures) appear to indicate that they are safe to use. However, > > it may choose the wrong headers in some mailserver configurations. > > (More discussion of this can be found in bug 2142 and bug 4747 in > > the SpamAssassin BugZilla.) > > > > To avoid this heuristic failure, the "envelope_sender_header" > > setting may be helpful. Name the header that your MTA or MDA adds to > > messages containing the address used at the MAIL FROM step of the > > SMTP transaction. > > > > If the header in question contains "<" or ">" characters at the > > > > start and end of the email address in the right-hand side, as in the > > SMTP transaction, these will be stripped. > > > > If the header is not found in a message, or if it's value does not > > contain an "@" sign, SpamAssassin will issue a warning in the logs > > and fall back to its default heuristics. > > > > (Note for MTA developers: we would prefer if the use of a single > > header be avoided in future, since that precludes 'downstream' spam > > scanning. > > "https://wiki.apache.org/spamassassin/EnvelopeSenderInReceived" > > details a better proposal, storing the envelope sender at each hop > > in the "Received" header.) > > > > example: > > > > envelope_sender_header X-SA-Exim-Mail-From > > > > On Friday, December 12th, 2025 at 9:18 PM, otto.cooper > > [email protected] wrote: > > > > > Hello, > > > > > > I encountered the following problem when using welcomelist_from_spf. > > > > > > The comand "spamassassin -t --debug <test.eml" shows that the rule fails, > > > because it is not using the envelope-from header. > > > > > > This is how the header is generated and used locally. > > > > > > The envelope-from header is not generated by default, so I added the > > > following rule in postfix's sender_access: > > > > > > /(.*)/ prepend X-Envelope-From: <$1> > > > > > > As a result, the header is added after the last Received. > > > > > > Additionally, a sub-header envelope-from is added as part of > > > Received-SPF, immediately after the last Received. > > > > > > Finally, in SpamAssassin, I set the following variables: > > > > > > > envelope_sender_header X-Envelope-From > > > > always_trust_envelope_sender 1 > > > > > > > loadplugin Mail::SpamAssassin::Plugin::SPF > > > > spf_timeout 5 > > > > ignore_received_spf_header 0 > > > > use_newest_received_spf_header 0 > > > > > > When running the debugger, this is what I see. > > > > > > > [...] dbg: message: X-Envelope-From header found after 1 or more > > > > Received lines, cannot trust envelope-from > > > > > > > [...] dbg: spf: EnvelopeFrom not found in first external Received header > > > > [...] dbg: spf: EnvelopeFrom header not found > > > > [...] dbg: spf: cannot get EnvelopeFrom, cannot use SPF by DNS > > > > > > The test.eml contains a single Received-SPF. > > > > > > What is the problem? > > > > > > SA is ignoring envelope_sender_header, and looking for EnvelopeFrom > > > instead of X-Envelope-From. > > > > > > SA is ignoring the envelope-from included in the Received-SPF header. > > > > > > If I rename X-Envelope-From to EnvelopeFrom in test.eml, the debugger > > > shows that the header is found and used. > > > > > > I have a rule that says welcomelist_from_spf *@example.com from test.eml, > > > but the resulting score is still high. > > > > > > I used X-Envelope-From in a few postfix rules, and I can change it to > > > EnvelopeFrom if needed. > > > However, the envelope from is the address used in the Return-Path header, > > > which is included > > > by default and happens to be the topmost header, so no special header > > > ought to be added in the first place.
