Notix
Learn

DKIM: a signature on every message, and a selector to find the key.

DKIM lets a domain sign the mail it sends so a receiver can check that the message really came from that domain and was not altered on the way. The signature travels in a header; the public key sits in DNS at a name built from the selector and the domain. This page explains the mechanism and the selector. The record-by-record setup is on the SPF, DKIM and DMARC page.

How a signature is made and checked.

When a message leaves the sending service, the signer picks a set of headers to cover (at least From), normalises them and the body so harmless changes in transit do not break the check, hashes the body, and signs the headers plus that body hash with a private key. The result is a DKIM-Signature header added to the message. Nothing about the message itself is encrypted; the signature only proves two things, that the holder of the private key sent it and that the covered parts arrived unchanged.

The receiver reads two tags from that header, the signing domain in d= and the selector in s=, and asks DNS for a TXT record at <selector>._domainkey.<domain>. That record carries the public key in its p= tag. The receiver recomputes the body hash, verifies the signature with the public key, and records the outcome in an Authentication-Results header. An empty p= means the key has been revoked.

A DKIM-Signature header, trimmed
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=acme.com;
  s=notix; t=1757721600;
  h=from:to:subject:date:message-id:mime-version:content-type;
  bh=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN/XKdLCPjaYaY=;
  b=dzdVyOfAKCdLXdJOc9G2q8LoXSlEniSbav+yuU4zGeeruD00lszZVoG4ZHRNiYzR...
The key the receiver fetches for d=acme.com, s=notix
$ dig +short TXT notix._domainkey.acme.com
"p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC..."

The tags in the header.

DKIM-Signature tags and their meanings
TagStatusMeaning
v=1RequiredThe DKIM version. Always 1.
a=rsa-sha256RequiredThe signing algorithm. rsa-sha1 is no longer allowed for signing or verifying.
d=acme.comRequiredThe signing domain: who is taking responsibility for the message. DMARC compares this to the From domain.
s=notixRequiredThe selector: which public key under the domain to fetch. Combined with d= it names the DNS record.
h=from:to:subject:dateRequiredThe header fields covered by the signature, in the order they were hashed.
bh=RequiredThe hash of the canonicalised body.
b=RequiredThe signature itself, base64, over the selected headers and the body hash.
c=relaxed/relaxedOptionalHeader and body canonicalisation. Defaults to simple/simple; relaxed survives whitespace changes in transit.
t= and x=RecommendedWhen the signature was made and when it expires, as Unix timestamps.
i=OptionalThe agent or user the signer is signing for. Defaults to @ plus the d= domain.

What the selector is for.

A domain has one name but can have many keys. The selector is the part of the DNS name that says which one. Without it, a domain could publish exactly one DKIM key, and every service that sends on its behalf would have to share the private half of it. With it, each sender publishes its own key under its own selector: your application mail through Notix under notix, your Google Workspace under google, a marketing tool under whatever it chooses. Each signs with a key only it holds, and a receiver checks each signature against the right record.

The selector is also how keys are rotated. Publish the new key under a new selector, switch the signer to it, leave the old record in place until mail signed with the old key has stopped arriving, then remove it. RFC 6376 warns against reusing a selector for a new key: once the old record is gone, a receiver cannot tell a legitimate message signed last week from a forged one, because both now fail the same way.

The Notix record.

When you add a domain, Notix generates an RSA key pair, keeps the private key with the sending infrastructure and shows you the public key to publish. The selector is notix. The record is a TXT at notix._domainkey on the domain you verified, and its value is p= followed by the public key. Verify a subdomain such as mail.acme.com and the record moves with it, to notix._domainkey.mail.acme.com; the dashboard shows the full name either way, and the DKIM row turns green once the record has propagated and been checked. Keys are 1024-bit RSA, which is the minimum RFC 8301 allows a signer to use and the minimum every verifier must accept; 2048 bits is the RFC's recommendation for new keys, and a key of either length verifies at every major mailbox provider today.

Alignment: the part DMARC cares about.

A valid signature proves the d= domain signed the message. It does not on its own prove that the address the reader sees in From is honest, because any domain can sign any message. DMARC closes that gap with alignment: a DKIM pass only counts for DMARC when the d= domain and the From domain match. In relaxed mode, the default, they need only share an organisational domain, so d=acme.com aligns with alerts@news.acme.com. In strict mode, set with adkim=s, the two must be identical. This is why a provider signing with its own domain gives you a DKIM pass and a DMARC failure at the same time, and why verifying your own domain is not optional if you publish a DMARC policy. The record options are on the DMARC page.

Reading the result.

Every large mailbox provider writes what it found into an Authentication-Results header you can read by viewing the original message. The DKIM part names the selector and signing domain it checked and gives a verdict; a failure usually carries a reason.

A pass and a fail, as Gmail reports them
Authentication-Results: mx.google.com;
  dkim=pass header.i=@acme.com header.s=notix header.b=dzdVyOfA;
  spf=pass (google.com: domain of bounce@mail.acme.com designates ...) ...;
  dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=acme.com

Authentication-Results: mx.google.com;
  dkim=fail (body hash did not verify) header.i=@acme.com header.s=notix;
  ...

dkim=pass with dmarc=pass is the outcome you want. dkim=fail (body hash did not verify) means the message was changed after signing, most often by a forwarder or a gateway rewriting links. dkim=neutral or permerror with a note about the key usually means the DNS record is missing, has a typo in the name, or was published under a different selector from the one the signer uses. dkim=pass with dmarc=fail is the alignment problem above.

Rotation and hygiene.

Rotate keys on a schedule and immediately if a private key may have leaked. Use a fresh selector each time. Keep only the selectors that are still in use published; a stale record with a key nobody signs with is harmless, but a stale record with a key that was compromised is a forgery kit. Sign with rsa-sha256; rsa-sha1 has been forbidden since RFC 8301. And if a rotation ever changes the Notix record, the dashboard shows the new value and the DKIM status returns to pending until the new record is found.

FAQ

Questions, answered.

What is a DKIM selector?
The selector is the s= tag in a DKIM-Signature header. It names which public key under the signing domain a receiver should fetch: the record lives at <selector>._domainkey.<domain>. A domain can publish as many selectors as it likes, so several services can sign for the same domain and a key can be rotated by publishing a new selector before the old one is removed. Notix uses the selector notix.
Where do I put the DKIM record?
In DNS, as a TXT record. For a domain verified with Notix the name is notix._domainkey on the domain you verified, and the value is p= followed by the public key the dashboard shows you. If you verified a subdomain such as mail.acme.com, the record goes at notix._domainkey.mail.acme.com. The setup walkthrough with every record is on the SPF, DKIM and DMARC page.
Why does each sending service need its own selector?
Because each service signs with its own private key, and the selector is how a receiver finds the matching public key. Your app mail through Notix, your marketing tool and your Google Workspace can all sign for acme.com at once because each publishes under a different selector. Reusing a selector for a new key is a mistake: a receiver can no longer tell an old, now-invalid signature from a forgery.
What key size should a DKIM key be?
RFC 8301 sets 1024 bits as the minimum a signer may use and the minimum a verifier will accept, and recommends 2048 bits. Verifiers must accept keys from 1024 up to 4096 bits. A 2048-bit key is the safe default for a new setup; a 1024-bit key still verifies everywhere today. Notix currently issues 1024-bit RSA keys for verified domains.
What is DKIM alignment, and why does DMARC care?
DMARC only counts a DKIM pass if the d= domain in the signature aligns with the domain in the visible From address. In relaxed mode, the default, the two only need to share an organisational domain, so d=acme.com aligns with a From of alerts@news.acme.com. In strict mode, set with adkim=s in the DMARC record, they must match exactly. A signature from a provider's own domain passes DKIM but never aligns, which is why you verify your own domain rather than send from a shared one.
Why does my DKIM signature pass at the sender but fail at the receiver?
Almost always because something changed the message in transit after it was signed: a mailing list adding a footer, a gateway rewriting links or wrapping long lines, or a forwarder altering the subject. The body hash no longer matches and the receiver reports a failure like "body hash did not verify". Relaxed canonicalisation tolerates whitespace changes but not content changes. Signing only the headers you control and expecting forwarded mail to rely on ARC or DMARC's SPF path is the usual answer.

Verify a domain and the record is written for you.

Add the domain, copy the TXT record the dashboard shows, and DKIM turns green when it propagates. Domain Connect providers get one click.