SPF Verification Result Reference
This document describes the result object returned by the spf() function.
The spf function verifies the SPF (Sender Policy Framework) record for an email sender and returns an object containing the verification result.
const { spf } = require ( 'mailauth/lib/spf' ) ;
const result = await spf ( {
sender : 'user@example.com' ,
ip : '192.0.2.1' ,
helo : 'mail.example.com' ,
mta : 'mx.receiver.com'
} ) ;
Field
Type
Presence
Description
domain
string
Always
The domain extracted from the sender address for SPF lookup
client-ip
string
Always
The client IP address that was checked
helo
string
If provided
The EHLO/HELO hostname from the SMTP session
envelope-from
string
If provided
The MAIL FROM address
status
object
Always
Verification status object (see below)
header
string
Always
Formatted Received-SPF header value
info
string
Always
Formatted Authentication-Results header value
rr
string
Record found
Raw SPF DNS TXT record
lookups
object
Always
DNS lookup statistics (see below)
Field
Type
Description
result
string
SPF result code (see below)
comment
string
Human-readable explanation of the result
smtp
object
SMTP session identifiers
Field
Type
Description
mailfrom
string
The MAIL FROM address
helo
string
The HELO/EHLO hostname
Field
Type
Description
limit
number
Maximum DNS lookups allowed (default: 10)
count
number
Number of DNS lookups performed
void
number
Number of void (empty result) DNS lookups
subqueries
object
Counts of DNS queries by type (e.g., {A: 2, MX: 1})
Result
SPF Qualifier
Description
pass
+
Sender is authorized
fail
-
Sender is explicitly not authorized
softfail
~
Sender is probably not authorized (transitional)
neutral
?
No policy assertion about the sender
none
-
No SPF record found or invalid domain
permerror
-
Permanent error (invalid SPF record, too many DNS lookups)
temperror
-
Temporary error (DNS timeout, server refused)
Comment Format
The status.comment field follows this format based on the result:
Result
Comment Format
pass
"{mta}: domain of {sender} designates {ip} as permitted sender"
fail
"{mta}: domain of {sender} does not designate {ip} as permitted sender"
softfail
"{mta}: domain of transitioning {sender} does not designate {ip} as permitted sender"
neutral
"{mta}: {ip} is neither permitted nor denied by domain of {sender}"
none
"{mta}: {domain} does not designate permitted sender hosts"
permerror
"{mta}: permanent error in processing during lookup of {sender}: {text}"
temperror
"{mta}: error in processing during lookup of {sender}: {text}"
{
"domain" : " example.com" ,
"client-ip" : " 192.0.2.1" ,
"helo" : " mail.example.com" ,
"envelope-from" : " user@example.com" ,
"status" : {
"result" : " pass" ,
"comment" : " mx.receiver.com: domain of user@example.com designates 192.0.2.1 as permitted sender" ,
"smtp" : {
"mailfrom" : " user@example.com" ,
"helo" : " mail.example.com"
}
},
"header" : " Received-SPF: pass (mx.receiver.com: domain of user@example.com designates 192.0.2.1 as permitted sender) client-ip=192.0.2.1;" ,
"info" : " spf=pass (mx.receiver.com: domain of user@example.com designates 192.0.2.1 as permitted sender) smtp.mailfrom=user@example.com smtp.helo=mail.example.com" ,
"rr" : " v=spf1 ip4:192.0.2.0/24 -all" ,
"lookups" : {
"limit" : 10 ,
"count" : 1 ,
"void" : 0 ,
"subqueries" : {}
}
}
{
"domain" : " example.com" ,
"client-ip" : " 203.0.113.1" ,
"helo" : " attacker.example.net" ,
"envelope-from" : " user@example.com" ,
"status" : {
"result" : " fail" ,
"comment" : " mx.receiver.com: domain of user@example.com does not designate 203.0.113.1 as permitted sender" ,
"smtp" : {
"mailfrom" : " user@example.com" ,
"helo" : " attacker.example.net"
}
},
"header" : " Received-SPF: fail (mx.receiver.com: domain of user@example.com does not designate 203.0.113.1 as permitted sender) client-ip=203.0.113.1;" ,
"info" : " spf=fail (mx.receiver.com: domain of user@example.com does not designate 203.0.113.1 as permitted sender) smtp.mailfrom=user@example.com smtp.helo=attacker.example.net" ,
"rr" : " v=spf1 ip4:192.0.2.0/24 -all" ,
"lookups" : {
"limit" : 10 ,
"count" : 1 ,
"void" : 0 ,
"subqueries" : {}
}
}
{
"domain" : " no-spf.example.com" ,
"client-ip" : " 192.0.2.1" ,
"helo" : " mail.no-spf.example.com" ,
"envelope-from" : " user@no-spf.example.com" ,
"status" : {
"result" : " none" ,
"comment" : " mx.receiver.com: no-spf.example.com does not designate permitted sender hosts" ,
"smtp" : {
"mailfrom" : " user@no-spf.example.com" ,
"helo" : " mail.no-spf.example.com"
}
},
"header" : " Received-SPF: none (mx.receiver.com: no-spf.example.com does not designate permitted sender hosts) client-ip=192.0.2.1;" ,
"info" : " spf=none (mx.receiver.com: no-spf.example.com does not designate permitted sender hosts) smtp.mailfrom=user@no-spf.example.com smtp.helo=mail.no-spf.example.com" ,
"lookups" : {
"limit" : 10 ,
"count" : 1 ,
"void" : 1 ,
"subqueries" : {}
}
}
SPF Permerror (Too Many Lookups)
{
"domain" : " complex.example.com" ,
"client-ip" : " 192.0.2.1" ,
"envelope-from" : " user@complex.example.com" ,
"status" : {
"result" : " permerror" ,
"comment" : " mx.receiver.com: permanent error in processing during lookup of user@complex.example.com: Too many DNS requests" ,
"smtp" : {
"mailfrom" : " user@complex.example.com"
}
},
"header" : " Received-SPF: permerror (mx.receiver.com: permanent error in processing during lookup of user@complex.example.com: Too many DNS requests) client-ip=192.0.2.1;" ,
"info" : " spf=permerror (mx.receiver.com: permanent error in processing during lookup of user@complex.example.com: Too many DNS requests) smtp.mailfrom=user@complex.example.com" ,
"lookups" : {
"limit" : 10 ,
"count" : 11 ,
"void" : 0 ,
"subqueries" : {
"include" : 5 ,
"a" : 3 ,
"mx" : 2
}
}
}