"Why are my emails going to spam?" has a short answer: an email goes to spam when the receiving server can't prove the message really came from the domain it claims to come from — and three TXT records called SPF, DKIM and DMARC are what provide that proof. But the short answer hides three completely different events under one name: a message that is accepted and lands in the spam folder, a message that bounces with a 550 code, and a message that sits in a queue for days, neither arriving nor producing a bounce. No single prescription cures all three. In this guide we first tell those three cases apart, then read the Authentication-Results header of a real message and branch on its result, then build SPF, DKIM and DMARC to the current version of the standards and put them in the authoritative DNS zone — and we say honestly where your hands are tied on shared hosting.
Emails going to spam, or not arriving at all? Tell the two apart first
Before you change anything in DNS, you need to know what the destination server did with your email. There are three common outcomes. First: the destination accepts the message with a 250 response, but its content filter drops it into the spam folder; no bounce is generated, so waiting for an error message is pointless. Second: the destination answers with a code from the 5xx family, and your server sends you a non-delivery report with the exact error text. Third: a 4xx code means "not now, try again later"; the message sits in the queue for several days, and throughout that time it has neither arrived nor bounced, until it is finally delivered or turns into a permanent bounce. There is also a fourth, rarer case: the destination accepts the message with a 250 and then silently discards it; you get no sign of this except that the message never arrives, and the only way to see it is to read the rua reports.
The first digit of the SMTP code tells the whole story: 4 means temporary, 5 means permanent. The right test is to send the message through the same path that has the problem — if the complaint is about the contact form, send from the form itself, not from webmail — to a Gmail address and an Outlook address at the same time. Then note three things: whether it arrived, which folder it landed in, and whether a non-delivery report came back.
One more distinction is needed, because the whole SPF and DMARC discussion rests on it: every message has two sender addresses. The envelope address, or MAIL FROM, is recorded in the Return-Path header and the user never sees it; the From header is the one the recipient sees. The two can be completely different, and SMTP raises no objection.
Where to find the Authentication-Results header, and how to read it
In Gmail, open the message, choose "Show original" from the three-dot menu and look for the Authentication-Results header; its format is standardized in RFC 8601. The example below is the typical shape of an invisible failure:
Authentication-Results: mx.google.com;
dkim=pass header.i=@mailer.example.net header.s=s1;
spf=pass (google.com: domain of bounce-42@mailer.example.net designates
203.0.113.10 as permitted sender) smtp.mailfrom=bounce-42@mailer.example.net;
dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=example.com
SPF and DKIM both show pass, and DMARC still failed. The reason is at the end of each line: the verified domain is mailer.example.net, but the From header says example.com — the problem we unpack in the DMARC alignment section. The other branches:
- All three pass. Authentication is sound; the problem is IP reputation, content or the recipients' complaint rate — see the sections on sender requirements and shared IPs and blacklists.
- spf=fail or softfail, but dkim=pass and dmarc=pass. The SPF record doesn't cover the server that currently sends your mail, and the DKIM signature saved the day; you still need to complete SPF.
- spf=permerror. The record is broken, either in its syntax or in its lookup budget — usually two SPF records at once, or more than the limit of ten DNS lookups.
- dkim=none or dkim=fail. In the first case the server doesn't sign at all; in the second, the signature doesn't match the public key — either the key sits incomplete in DNS, or something modified the message in transit.
- dmarc=none. You haven't published a DMARC record; for bulk sending to Gmail, that alone is enough to get messages rejected with 550 5.7.40.
In messages delivered to Outlook, the same header also has a compauth field: the combined result of authentication and sender reputation, as described in Microsoft's email authentication documentation.
Bouncing emails: Gmail error codes such as 550 5.7.26 and exactly what they mean
A non-delivery report carries the raw text of the receiving server's reply and tells you exactly why your email bounced; the important part looks like this:
Final-Recipient: rfc822; user@gmail.com
Action: failed
Status: 5.7.26
Diagnostic-Code: smtp; 550-5.7.26 This mail has been blocked because the sender is
unauthenticated. Gmail requires all senders to authenticate with either SPF or DKIM.
Google publishes the full list of these codes in its Gmail SMTP error code reference:
| Code | Exact meaning | What to do |
|---|---|---|
| 550 5.7.26 | The sender is unauthenticated, or SPF for the MAIL FROM domain failed under -all, or the message was rejected because of the sending domain's own DMARC policy — Google publishes all three texts under this one code | Fix at least one of SPF or DKIM for this sending path, and read the full error text to find out which case you have |
| 550 5.7.27 | In bulk sending, the message failed the SPF check | Add the sending server's IP or include to your SPF record |
| 550 5.7.30 | In bulk sending, the message failed the DKIM check | Turn on DKIM and publish the public key in DNS |
| 550 5.7.40 | The domain has no DMARC record, or the record sets no policy | Publish a _dmarc record, at least with p=none |
| 550 5.7.25 | The sending IP has no PTR, or the PTR doesn't resolve back to the same IP | On shared hosting this is the provider's job; open a ticket |
| 421 4.7.26 | Temporary: unauthenticated mail is being rate-limited | Same cure as 5.7.26; the queue retries on its own |
| 451 4.7.26 | Temporary: DMARC doesn't allow the message, and a transient DNS error prevented authentication | Check that the domain's nameservers are reachable |
Two notes. Google's text for 5.7.27 and 5.7.30 explicitly refers to "bulk senders", so if your site sends ten messages a day and still sees these codes, your server's shared IP has been classed as a bulk sender. And 451 4.7.26 is not an SPF or DKIM problem — the cure is stable nameservers.
What is an SPF record, and why is it so often set up wrong?
SPF is a TXT record on the domain itself that lists which servers are allowed to send email in that domain's name. The receiver checks the IP of the server talking to it against this list and reports the result as none (the domain has no SPF record at all — the most common case), pass, fail, softfail, neutral, or an error (temperror and permerror):
dig +short TXT example.com
"v=spf1 ip4:203.0.113.10 include:_spf.example.net ~all"
A crucial point that many guides leave out: SPF checks the MAIL FROM domain — and when MAIL FROM is empty, as with bounce messages, the host name announced in HELO/EHLO — and has nothing to do with the From header. In other words, SPF can be completely correct and the message can still be flagged as forged. Its second weakness is forwarding: the forwarding server isn't on your list, so the result becomes fail.
Five common SPF record mistakes
RFC 7208 sets limits that, if you ignore them, make the record useless:
- Two SPF records at once. Section 3.2 says a domain must not have more than one selectable record; a second record means permerror and, in practice, no SPF at all.
- Going over the limit of ten DNS lookups. Section 4.6.4 caps these lookups at 10, and every include, a, mx, ptr, exists and redirect counts — nested ones included. Some includes are cheap and some are expensive, and the way to measure them is to open the record itself: dig +short TXT _spf.google.com currently returns a flat record containing nothing but ip4 and ip6 entries, so its entire cost is that single include lookup; but if you see another include in the output, those count too — and the includes of some marketing services nest several layers deep. Repeat this check for every service you include, because a provider's record can change without notice.
- Relying on the ptr mechanism. Section 5.5 says it should not be published, because it is slow and puts a heavy load on nameservers.
- An overly long record. Section 3.4 only recommends that the query response fit in 512 octets; that is a SHOULD, and with EDNS0 it is rarely a problem today. The hard limit that actually breaks a record is the 255 bytes of each TXT string — if your SPF record goes past it, split it, just as with DKIM, into several quoted strings inside one record.
- Choosing -all without thinking it through. It means "anything not on this list is forged", and the text of Gmail's 550 5.7.26 error points at exactly this. Until you are sure you know every sender, ~all is safer.
Half of all SPF errors are really TXT syntax errors; if the TXT syntax hasn't clicked for you yet, read our guide to DNS records first.
What is DKIM? A digital signature that travels with the email itself
DKIM is a cryptographic signature that the sending server puts on parts of the message — including the From header and the body — and carries in the DKIM-Signature header. The private key stays on the server, and the public key is published in DNS at selector._domainkey.example.com. Its advantage over SPF is that the signature travels inside the message, so forwarding doesn't break it.
Why a 2048-bit DKIM key doesn't fit in one string
RFC 8301 says signers must use keys of at least 1024 bits and should use 2048-bit keys. Measure the real size of p= yourself:
openssl genrsa -out dkim.pem 2048
openssl rsa -in dkim.pem -pubout -outform DER | base64 -w0 | wc -c
392
So p= for a 2048-bit key is exactly 392 base64 characters, and with the v=DKIM1; k=rsa; p= prefix it comes to about 410 characters — while RFC 1035 caps each "character-string" in DNS at 255 bytes. The answer is not two TXT records; it is one TXT record holding several quoted strings in a row, which the receiver joins together without spaces:
dig +short TXT mail._domainkey.example.com
"v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB...first 255 bytes..." "...remainder of the base64 key...IDAQAB"
The -w0 switch is specific to the GNU version of base64; on macOS or BSD, run openssl rsa -in dkim.pem -pubout -outform DER | openssl base64 -A | wc -c instead. There is also a way around this whole issue: RFC 8463 added the ed25519-sha256 algorithm to DKIM, whose public key is only 44 base64 characters, so the 255-byte problem never comes up; but receiver support for it is not complete yet, so if you go that way, sign every message with an RSA key as well.
You can have several DKIM keys on one domain at the same time, because every message states in its signature which selector it was signed with.
SPF and DKIM in cPanel and DirectAdmin
Generating a DKIM key is a job for the control panel, not for your hands: in cPanel the path is Email → Email Deliverability, and in DirectAdmin (Evolution skin) it is the Enable DKIM button under E-Mail Manager → E-Mail Accounts; the record it creates then shows up in Account Manager → DNS Management. Both panels also generate a suggested SPF record on the same page. We go through their general differences in our comparison of free control panels. One thing we should say plainly: if your hosting is with Mehran Host, direct login to these pages is not open, and the right route to a panel-level DKIM key is a support ticket — the email on Mehran Host hosting section spells out exactly what is in your own hands.
What is a DMARC record, and what does it add to SPF and DKIM?
DMARC is a third TXT record, published at _dmarc.example.com, and it does three things: it requires the domain verified in the email to be aligned with the domain in the From header, it decides what happens to mail that isn't aligned, and it gives an address for aggregate reports. Without DMARC, a pass in SPF or DKIM says nothing about the name the user actually sees.
The standard has changed: pct no longer exists
Read this section carefully, because most guides you will find are out of date on exactly this point. In May 2026 three documents — RFC 9989, RFC 9990 and RFC 9991 — were published and made RFC 7489 obsolete. The pct= tag, together with rf= and ri=, has been removed from the standard; if you see advice somewhere to start with pct=10, that text dates from before 2026.
Its place has been taken by t=. Its default is n, and with t=y the receiver, according to the standard's text, acts one step more leniently: with p=quarantine it behaves as none, and with p=reject as quarantine. The tag is meaningless with a none policy. The other new tag is np=, which sets the policy only for non-existent subdomains — exactly where spoofers go — and when it is absent, sp= and then p= apply. In other words, np is only worth setting when the main policy is more lenient, because with p=reject and no sp, non-existent subdomains inherit that same reject.
A practical warning about t=, though: RFC 9989 was only published in May 2026, and most large receivers haven't implemented this tag yet. The standard itself says a receiver must ignore an unknown tag and apply the rest of the record, so today p=quarantine; t=y gets real quarantine at many receivers, not none-like behavior. Until receiver support is clear, the safe step is to stay on p=none and read the rua reports, and to treat t=y as a statement of your intent, not a guarantee.
The bigger change in DMARCbis lies elsewhere, however. Until now, a receiver relied on the Public Suffix List (PSL) to find the "organizational domain". RFC 9989 defines a new method called the "DNS tree walk": the receiver climbs from the From header's domain one label at a time, looking for a DMARC record, and to prevent abuse, a domain with more than eight labels still costs no more than eight queries. The practical consequence for you: if you send email from subdomains, publishing a DMARC record on that subdomain is no longer an optimization — it determines which policy gets applied.
The migration ladder, without pct
The safe path has four steps, and each step needs at least two weeks:
# step 1 - observe only, and shut the door on non-existent subdomains from day one
_dmarc.example.com. IN TXT "v=DMARC1; p=none; np=reject; rua=mailto:dmarc@example.com"
# step 2 - quarantine; t=y signals testing, but assume most receivers ignore it today
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; t=y; np=reject; rua=mailto:dmarc@example.com"
# step 3 - real quarantine
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; np=reject; rua=mailto:dmarc@example.com"
# step 4 - enforce
_dmarc.example.com. IN TXT "v=DMARC1; p=reject; rua=mailto:dmarc@example.com"
Don't skip the first step. rua reports are compressed XML files that list which IPs have sent mail in your domain's name. There are almost always one or two forgotten senders that jumping straight to p=reject would have cut off without a sound.
What is DMARC alignment, and why do healthy SPF and DKIM still fail?
Alignment in DMARC means the domain verified by SPF or DKIM must be the same as the From header's domain, or belong to the same organizational domain. That is the core of DMARC, and the reason for the invisible failure we saw in the Authentication-Results header example: both checks pass, and DMARC fails anyway. In "relaxed" mode it is enough for the two to share an organizational domain, for example news.example.com and foo.example.com; in "strict" mode they must be identical. The default for adkim and aspf is relaxed. Keep in mind that the "organizational domain" is now determined by the DNS tree walk, not by the Public Suffix List; for ordinary domains the result is the same, but on multi-part suffixes it may come out differently — there, check the result against your rua reports rather than assuming.
The classic scenario: a third-party email service sends the message with its own domain in MAIL FROM; SPF passes for the service's domain, but that domain has no relationship to example.com in the From header. There are two cures, and both are set up in that service's dashboard: either have it sign your messages with your domain's DKIM key — that is, d=example.com in the signature — or define a dedicated Return-Path subdomain in your DNS that points to their service.
Subdomains have a trap of their own: each subdomain needs its own SPF record and does not inherit one. If you send transactional email from mail.example.com and SPF only sits on example.com, those messages have no SPF.
Which DNS zone should hold your SPF and DKIM records? Three panels that get mixed up
This is the most common reason a correct fix has no effect: the right record, in a zone nobody reads. There are three levels, and only one of them is authoritative — the one your domain's nameservers point to.
The first level is your domain registrar's panel; its DNS section is authoritative only if the nameservers have been left on the registrar's own nameservers. The second level is a managed DNS panel — wherever the nameservers have been delegated. The third level is the DNS zone of the hosting account itself. If your hosting is with Mehran Host, you edit this zone from the "DNS" tab in the Mehran Host panel — direct login to cPanel or DirectAdmin is not open by default — and that tab accepts A, AAAA, CNAME, TXT and MX records, which is enough for all three records in this article. With any other host, the same zone is in the DNS tab of cPanel or DirectAdmin. Either way there is one condition: it only takes effect if the domain's nameservers point to that host. The definitive way to tell is to ask the authoritative nameserver directly:
# 1) which nameservers are authoritative for the domain?
dig +short NS example.com
ns1.example-dns.com.
ns2.example-dns.com.
# 2) ask that nameserver directly, bypassing every cache
dig +short TXT example.com @ns1.example-dns.com
dig +short TXT _dmarc.example.com @ns1.example-dns.com
dig +short TXT mail._domainkey.example.com @ns1.example-dns.com
Two notes on these commands. First, dig +short NS gives you the NS list inside the zone itself, not the delegation registered at the registry; if an old zone holds stale NS records, this very command sends you to the wrong server, so when in doubt, ask the TLD servers instead: dig +short NS example.com @a.gtld-servers.net. Second, +short also comes back empty on SERVFAIL and REFUSED; to tell "no record" apart from "the server didn't answer", run it once without +short and look at the status line. With that distinction made, an empty result in the second step means your record is not in the right zone. One last point is timing: in Mehran Host's DNS panel the minimum TTL is 60 seconds and the default is 3,600 seconds; if you are going to change a record several times, lower the TTL before you start and raise it again once everything has settled. Reviewing MX and SPF is also one of the forgotten steps of a move to a new host, and we include it in our roadmap for migrating a website without downtime.
Gmail, Yahoo and Outlook sender requirements
Google and Yahoo began enforcing their email sender requirements in February 2024, and Microsoft joined them more than a year later, in May 2025. Gmail's sender guidelines require from all senders: at least one of SPF or DKIM, a TLS connection, a valid and matching PTR record, formatting that follows RFC 5322, and a spam rate below 0.3% as measured in Postmaster Tools — Google gives the real target as below 0.1%, with 0.3% as a ceiling you should never reach. Bulk senders — 5,000 or more messages a day to personal Gmail accounts, and according to Google a domain that crosses this threshold once stays a bulk sender even if its volume drops — need both SPF and DKIM, plus a DMARC record (even with p=none), alignment of the From domain, and one-click unsubscribe with the List-Unsubscribe and List-Unsubscribe-Post headers.
Yahoo's sender guidelines ask for almost the same, with a complaint rate below 0.3% and unsubscribe requests honored within two days. In April 2025 Microsoft announced, for high-volume Outlook senders, that domains sending 5,000 or more messages a day to consumer outlook.com, hotmail.com and live.com mailboxes must have all three. The first announcement said non-compliant mail would go to Junk, but a few days later Microsoft amended that text: since May 5, 2025, non-compliant mail is rejected during the SMTP session itself with the permanent error 550 5.7.515 Access denied, sending domain does not meet the required authentication level — not filtered, not sent to Junk. This requirement doesn't cover Microsoft 365 business mailboxes. The conclusion is clear: SPF + DKIM + DMARC is no longer "something for the pros"; it is the minimum for getting your mail accepted.
Why do WordPress emails go to spam? The mail() function and authenticated SMTP
By default, WordPress uses PHP's mail() function, which hands the message straight to the server's local mail service without any username or password. That has two important consequences. First, the envelope address is chosen by the system and is usually a system user at the server's host name, not at the site's domain — so SPF is checked for a domain that isn't yours. Second, many contact form plugins put the visitor's own address in the From header; the result is that your server claims the message came from gmail.com, and that domain's DMARC rejects it straight away.
The right setup is sending over authenticated SMTP on the message submission port defined in RFC 6409:
SMTP host: mail.example.com
Port: 587 # STARTTLS (465 = implicit TLS; 25 is often blocked outbound)
Encryption: STARTTLS
Username: noreply@example.com
From: noreply@example.com # must be a mailbox on YOUR domain
Reply-To: set by the form plugin to the visitor's address
The golden rule for contact forms is that last line: the visitor's address goes in Reply-To, not in From. That way the "Reply" button still works as expected, and the message stays aligned with your own domain's identity. You also need a valid TLS certificate for that same host name; how to issue one is covered in our guide to installing a free SSL certificate with Certbot.
Shared IPs, PTR records and blacklists — the honest section
Now we reach the boundary that is out of your hands on shared hosting. The IP your email goes out from belongs to the provider, and dozens of other sites send from it as well. The PTR record — the reverse lookup whose absence Gmail answers with 550 5.7.25 — is set on that IP, and only the holder of the address block can change it. You can, however, see its state:
# reverse lookup of the sending IP, then confirm it resolves forward again
dig +short -x 203.0.113.10
mail.example-host.com.
dig +short A mail.example-host.com
203.0.113.10
If these two don't match, the PTR isn't consistent and you get that same 550 5.7.25; the only route is a support ticket. The second consequence of a shared IP is shared reputation: a neighbor's spam drags down that IP's reputation, and your mail lands in spam through no fault of its own. Checking blacklists is simple, but there is a trap:
# octets reversed, then the zone name appended
dig +short 10.113.0.203.zen.spamhaus.org
# empty / NXDOMAIN = not listed
# 127.0.0.2 .. 127.0.0.11 = listed; the code identifies which list
On shared hosting, asking to be removed from a blacklist is also the provider's job, because they have to show that the source of the spam has been shut down. The graduation point is a server with a dedicated IP on which you can set the PTR yourself — a capability that depends on the server provider, so ask whether it exists before you buy. We explain the difference between these two worlds in our comparison of shared hosting and a VPS. But to be honest: a brand-new dedicated IP starts with zero reputation and has to be warmed up with regular sending; on day one it is not necessarily better than a shared IP.
8 common mistakes that send email to spam
A summary of the patterns most responsible for a site's email bouncing or landing in spam — the last column tells you how to detect each one on your own domain:
| Mistake | Consequence | The right way | How to detect it |
|---|---|---|---|
| Two separate SPF records for one domain | permerror, and SPF stops working entirely | Merge all mechanisms into a single v=spf1 record | dig +short TXT example.com returns more than one v=spf1 line |
| The visitor's address in the contact form's From header | The visitor's domain fails DMARC and the message is rejected | From on your own domain, the visitor in Reply-To | dmarc=fail with header.from=gmail.com in the bounced message's header |
| Record created in the hosting DNS tab while the nameservers are elsewhere | The record is never read | Edit the zone the domain's NS records point to | A direct query to the authoritative nameserver comes back empty, yet status is NOERROR |
| A 2048-bit DKIM key in one long string | p= gets truncated, and dkim=fail becomes permanent | One TXT record with several strings, each under 255 bytes | The p= value in the dig output is shorter than 392 characters |
| Jumping straight from no DMARC to p=reject | Forgotten legitimate senders are cut off without a sound | p=none with rua, then quarantine, and finally reject | rua reports show IPs you don't recognize |
| Using pct= because old guides say so | An up-to-date receiver ignores it and applies the full policy, while an old receiver still honors it — so p=reject; pct=10 rejects 10% at one and 100% at the other | Remove pct from the record and climb the steps by changing p= itself | dig +short TXT _dmarc.example.com still shows pct= |
| Going over the ten-DNS-lookup limit with nested includes | permerror at every receiver | Remove unused services and replace include with ip4 | Open each include and count its nested includes; the total goes over 10 |
| No SPF and DKIM on the sending subdomain | Transactional mail goes out unauthenticated | A separate record for each subdomain, because nothing is inherited | dig +short TXT mail.example.com is empty while the main domain has a record |
Email on Mehran Host hosting
Let's be honest about which parts of this work happen in the Mehran Host panel and which don't. The customer panel manages your domain's mailboxes: creating and deleting mailboxes, changing passwords, storage quotas and forwarders. Generating a DKIM key and creating SPF and DMARC records automatically are not done in this panel; if you need a panel-level DKIM key, the right route is a support ticket.
The DNS side, on the other hand, is in your hands: the managed DNS panel supports A, AAAA, CNAME, MX, TXT, NS, SRV and CAA records — and all three records in this article are TXT — with a minimum TTL of 60 seconds, a default of 3,600 seconds, and free nameservers. So if your domain's nameservers are delegated to this panel, you control the very authoritative zone we described in the section on where to create the record. And if your domain's nameservers point to the hosting server itself rather than to the DNS panel, your authoritative zone is the "DNS" tab on the hosting service's page; A, AAAA, CNAME, TXT and MX records are available there, and since all three records in this article are TXT, you can create them there as well. The number of mailboxes in each plan is shown on that plan's card on the web hosting page.
A practical note about the DKIM key: the DNS panel stores a TXT value exactly as you enter it and doesn't split a long string by itself. So split the roughly 410-character value of a 2048-bit key yourself into two parts of under 255 characters, and enter each part in quotes, one after the other on a single line — in the form "first part" "second part"; an unquoted value longer than 255 characters is not accepted. And one more thing, so that no wrong expectations form: the "Email records check" tool appears in the site's list of tools, but it is still under construction; until it ships, the dig commands above remain the most accurate method.
Frequently asked questions
Why are my website's emails going to spam?
Your site's emails usually go to spam because the receiving server couldn't prove the message really came from the domain it claims. Three TXT records provide that proof: SPF lists the authorized servers, DKIM puts a cryptographic signature on the message, and DMARC requires both to align with the visible From domain. To diagnose it, choose "Show original" in Gmail and read the Authentication-Results header; the results of all three checks are right there.
What is an SPF record, and how do I create one?
An SPF record is a TXT record on the domain itself that lists which servers are allowed to send mail in that domain's name; it looks like v=spf1 ip4:… include:… ~all. Create it in the domain's authoritative DNS zone, and respect three limits: only one SPF record per domain, no more than ten DNS lookups, and no use of the ptr mechanism.
What does the 550 5.7.26 error mean when sending email?
550 5.7.26 is a permanent rejection from Gmail, and it means the message arrived unauthenticated: neither SPF nor DKIM verified the sender, or SPF for the MAIL FROM domain failed under a -all policy. Because the first digit is 5, the message bounces for good. The cure is to fix at least one of SPF or DKIM so that it passes for that same sending path.
What is a DMARC record, and which policy should I start with?
DMARC is a TXT record at the domain's _dmarc name that says the domain verified by SPF or DKIM must align with the From header's domain, and what to do with unaligned mail. Start with p=none and an rua address, read the reports for two weeks, then move to quarantine and finally reject. The pct tag was removed in the 2026 standard and t=y took its place, but because major receivers haven't implemented t yet, climb the steps by changing p= itself.
Why doesn't my WordPress contact form email arrive?
WordPress contact form emails usually don't arrive because the form plugin puts the visitor's own address in the From header; your server then claims the message came from a domain like gmail.com, and that domain's DMARC policy rejects it. The right way is to keep From on a mailbox at your own domain and put the visitor's address in Reply-To. If the problem persists, switch sending from mail() to authenticated SMTP on port 587.