# SPF, DKIM and DMARC in cPanel DNS: Setup and Checks

Source: https://srvscripts.com/guides/spf-dkim-dmarc-cpanel-dns/
Updated: 2026-10-03
Publisher: srvScripts (https://srvscripts.com/)

Mail authentication is no longer optional. Gmail, Microsoft and Yahoo require SPF and DKIM alignment for any sender of volume and reject or junk unauthenticated mail, and DMARC is the record that tells them what to do when a check fails. cPanel & WHM can manage all three for domains whose DNS is hosted on the server: SPF and DKIM through Email Deliverability, and since version 132 an automatically generated DMARC record for new domains. This guide covers turning them on, checking the results and handling the cases where DNS lives at a registrar or CDN instead.

In short: Open WHM → Email → Email Deliverability and click Repair on each domain, or run whmapi1 install_spf_records and whmapi1 install_dkim_records for the domain, which write correct SPF and DKIM records into the local zone.

**Short answer:** Open WHM → Email → Email Deliverability and click Repair on each domain, or run `whmapi1 install_spf_records` and `whmapi1 install_dkim_records` for the domain, which write correct SPF and DKIM records into the local zone. Confirm a `_dmarc` TXT record exists with `dig +short TXT _dmarc.example.com` and add `v=DMARC1; p=none; rua=mailto:...` if it does not, then move to `p=quarantine` and `p=reject` once the reports show legitimate mail passing.

## SPF and DKIM through Email Deliverability

The central place is WHM → Email → Email Deliverability, which lists every domain on the server and flags each one whose SPF or DKIM records are missing or wrong. Selecting Repair on a domain writes the correct records to the local zone. cPanel users have the same view at cPanel → Email → Email Deliverability for their own domains.

From the shell, the same thing for a single domain:

```
whmapi1 install_spf_records domain=example.com
whmapi1 install_dkim_records domain=example.com
whmapi1 fetch_dkim_private_key domain=example.com | head -3
```

The generated SPF record looks like `v=spf1 +mx +a +ip4:203.0.113.10 ~all`, covering the server’s own IP, the MX hosts and the A record. If mail for the domain also goes out through a third-party relay, a marketing platform or a ticketing system, add its `include:` mechanism, keeping within the ten-lookup limit. WHM → Service Configuration → Exim Configuration Manager → Basic Editor has a “SPF include hosts for all domains” field for a relay that every domain uses, which is the correct place for a global smarthost such as MailBaby rather than editing each zone.

DKIM keys are stored under `/var/cpanel/domain_keys/private/` and `/var/cpanel/domain_keys/public/`, and the public key is published at `default._domainkey.example.com`. Exim signs outbound mail automatically when the key exists. Keys generated on current builds are 2048-bit; a domain with an old 1024-bit key can be rotated by deleting and reinstalling the DKIM records.

## The automatic DMARC record

Since version 132, when a new domain is created with local DNS, cPanel adds a DMARC record at `_dmarc.example.com` with a monitoring policy of `p=none`. This gives the domain a valid DMARC presence, which the major receivers now expect, without rejecting anything. Existing domains created before 132 do not get the record retroactively, so check for it:

```
dig +short TXT _dmarc.example.com
```

If it returns nothing, add one. In WHM → DNS Functions → DNS Zone Manager, or from the shell:

```
whmapi1 addzonerecord domain=example.com name=_dmarc.example.com. \
  type=TXT ttl=3600 txtdata='v=DMARC1; p=none; rua=mailto:dmarc@example.com'
```

Once the aggregate reports at the `rua` address confirm that legitimate mail passes, tighten to `p=quarantine` and then `p=reject`. Do not go straight to reject on a domain with unknown senders; the reports exist to find them.

## Long TXT records

Related to the same release, cPanel now handles TXT records longer than 255 characters correctly, splitting them into multiple quoted strings in the zone file. That matters for DKIM public keys and for SPF records that have grown. If you edit zone files by hand, write long values as adjacent quoted strings and cPanel will keep them intact; if you paste a 2048-bit DKIM key as a single 400-character string into the DNS Zone Manager on 132 or later, it will be split for you. On older builds it must be split manually or the zone will fail to load.

## When DNS is hosted elsewhere

Email Deliverability can only write records into zones the server is authoritative for. If the domain’s nameservers point at a registrar, a CDN or a separate DNS cluster, the interface will still show the expected values so they can be copied. Pull them programmatically:

```
uapi --user= EmailAuth get_dkim_records domain=example.com
uapi --user= EmailAuth get_spf_records domain=example.com
```

The `EmailAuth` calls return the exact record names and values. Publish them at the external provider, then use “Validate” in Email Deliverability, which does a live DNS lookup rather than reading the local zone.

For Cloudflare-hosted zones, the records must be added as TXT with the proxy disabled, which is the default for TXT. If the domain uses Cloudflare’s own email routing or a provider that rewrites mail, alignment can still fail on forwarded messages; our guide on [Cloudflare and cPanel DNS](/guides/cloudflare-cpanel-dns-proxy-real-ip/) covers the DNS side.

## Verify

Send a message from the domain to an external mailbox and inspect the headers for `Authentication-Results`. You want to see `spf=pass`, `dkim=pass` with the `d=` value matching the sending domain, and `dmarc=pass`. From the server, confirm the records resolve publicly:

```
dig +short TXT example.com | grep spf1
dig +short TXT default._domainkey.example.com
dig +short TXT _dmarc.example.com
```

The validate action in Email Deliverability performs the same lookups and reports mismatches between the expected and published values.

## Common pitfall

The commonest cause of DKIM failure on a cPanel server is a domain whose DNS moved away from the server after DKIM was enabled. The private key is still on the server and Exim still signs, but the public key was never published at the new DNS host, so every receiver sees `dkim=fail`. Email Deliverability shows this immediately as a mismatch; the fix is to copy the record out. The second pitfall is an SPF record with too many `include:` entries from marketing tools, which exceeds ten DNS lookups and evaluates as a permanent error. Count them, and flatten or remove the ones no longer used.

Diagram: SPF checks the sending IP, DKIM checks the signature against the DNS key, and DMARC needs one of them to pass and align with the From domain.

## SPF DKIM DMARC cPanel at a glance

**Official documentation:** [RFC 7489 (DMARC)](https://www.rfc-editor.org/rfc/rfc7489), [RFC 7208 (SPF)](https://www.rfc-editor.org/rfc/rfc7208), [RFC 6376 (DKIM)](https://www.rfc-editor.org/rfc/rfc6376).

**Related guides:** [Setting up Dovecot Sieve mail filters in Roundcube on cPanel](https://srvscripts.com/guides/dovecot-sieve-filters-roundcube-cpanel/) · [Whitelisting MailBaby in cPanel greylisting, CSF and SpamAssassin](https://srvscripts.com/guides/whitelist-mailbaby-cpanel/) · [Email forwarders with MailBaby: SRS, strict forwarding errors and backoffs](https://srvscripts.com/guides/mailbaby-srs-strict-forwarding-errors/).

## Frequently asked questions

### Does cPanel add DKIM and SPF automatically for new domains?

Yes. On current builds, new domains with local DNS get SPF and DKIM records at creation and, since version 132, a DMARC record with `p=none`. Domains whose DNS is hosted elsewhere still need the records copied out and published manually.

### How long does it take for SPF, DKIM and DMARC changes to take effect?

Receivers see the new records as soon as the old TTL expires, which is typically one hour to a day depending on the zone’s TTL. Lower the TTL in advance if a quick change is needed, and use the Validate action in Email Deliverability to confirm the live values.

### Can I set DMARC to p=reject straight away?

Not safely. Start with `p=none` and read the aggregate reports for a couple of weeks to catch legitimate senders such as marketing platforms or ticket systems that are not yet in SPF or signing with DKIM, then move to `p=quarantine` and finally `p=reject`.
