A safe DKIM key rotation is an overlap between two selector names, not an in-place replacement of one DNS value. Publish and verify the new public key first, switch one outbound mail stream to the matching private key, and keep the old selector available until no message signed with it can still reach a verifier. That sequence follows the selector model in RFC 6376 and preserves a clean rollback path.
Treating rotation as a DNS swap reverses the dependency. A signer can immediately create mail that names s=2026q3, while receivers still see no usable 2026q3._domainkey record. Replacing the key behind the old selector is worse: cached resolvers and fresh resolvers may return different public keys for the same selector, and the protocol no longer tells you whether a failed signature is stale or forged. RFC 6376 therefore calls selector reuse for new keys ill-advised.
This guide uses OpenDKIM on a Postfix-style Linux mail host as the concrete example, but the control flow applies to Rspamd, hosted senders and other DKIM signers: inventory, publish, prove, cut over, observe, retire. File locations and service users vary by distribution, so confirm the active configuration before adapting any command.
DKIM verification joins two states that are usually owned by different systems. The outbound signer chooses a private key and writes its selector into the DKIM-Signature header. Later, a receiver combines the s= selector with the d= signing domain and retrieves the public key from DNS. Neither lane can prove the change alone.
RFC 6376 explicitly designed selectors to support multiple concurrent public keys. During normal replacement, both public keys are advertised for a transition period, new outbound mail starts using the new key, and the old record is removed only after old-signed mail has had an opportunity to be verified. RFC 5863’s deployment guidance adds the operational requirement: signer and DNS administrators must coordinate publication, activation and withdrawal rather than treating key creation as a one-team task.
Rollback exists only while the old private key, old SigningTable mapping and old DNS record remain usable. Once any of those disappear, returning the signer to the previous selector cannot restore validation. Do not destroy rollback material during the same action that activates the new key.
One domain can send through a VPS, a help-desk platform, a billing system, a marketing provider and a cloud application. Each stream may use a different d= domain, selector, DNS owner or private-key custodian. Rotating only the selector visible on the main Postfix host can leave forgotten streams untouched or cause two teams to claim the same selector.
Collect a recently delivered message from every known stream and record its authentication headers. The evidence must include the visible From domain, DKIM d=, selector s=, signing algorithm a=, receiver result and the system that submitted the message. A DMARC report can help enumerate active signing domains, but it does not replace a message sample from each critical path.
On the OpenDKIM host, start with read-only discovery. These commands expose the supported algorithms, active table references, Postfix queue lifetime and service state without changing mail flow:
sudo opendkim -V
sudo grep -E '^(Domain|Selector|KeyFile|KeyTable|SigningTable|UserID)[[:space:]]' /etc/opendkim.conf
sudo postconf maximal_queue_lifetime bounce_queue_lifetime
sudo systemctl status opendkim --no-pager
Package layouts differ. Some systems keep tables under /etc/opendkim/, others use /etc/opendkim.conf plus distribution-specific include files, and database-backed deployments may not use flat files at all. If a command points to a missing path, stop and follow the references from the active KeyTable and SigningTable settings instead of creating a parallel configuration that the service never reads.
A useful inventory is small enough to review but precise enough to drive the change:
| Evidence | What it proves | Stop condition |
|---|---|---|
Delivered header with d=, s= and a= |
Which key a real receiver evaluated | An expected stream has no sample |
Authoritative DNS response for selector._domainkey |
Which team publishes the public key | Record owner or zone is unclear |
| KeyTable or provider identity mapping | Which signer holds the private key | More than one unexplained signer claims the selector |
| Queue lifetime and oldest queued message | How long old-signed mail may remain pending | Retention boundary is based only on a guessed number of days |
Receiver Authentication-Results |
Whether DKIM and DMARC alignment pass | Testing checks DNS only, not a delivered message |
Selector names do not need to contain secrets. A date or change identifier such as 2026q3 is operationally readable; RFC 6376 allows many naming strategies. What matters is that a new key receives a new selector and that the inventory can trace it to one signing boundary.
Normal rotation values continuity. A compromised private key values containment, so keeping it valid for a graceful overlap may be unacceptable. Decide which event you are handling before the window opens. If compromise is suspected, preserve evidence, stop unauthorized signing, revoke or remove the old public key according to incident policy, and accept that mail signed with the exposed key may fail verification.
Routine work should not inherit that emergency behavior. Immediate deletion during an ordinary rollover converts a controlled maintenance event into an authentication outage for delayed mail.
Key generation is the beginning of the change, not permission to activate it. The public record must be visible and must match the private key before any production message names the new selector.
RFC 8301 requires RSA keys of at least 1024 bits, recommends at least 2048 bits and forbids RSA-SHA1. The OpenDKIM example below explicitly requests a 2048-bit key so behavior does not depend on a package default. Replace the domain and selector, and confirm the service account from the active configuration before setting ownership.
sudo install -d -o opendkim -g opendkim -m 0750 /etc/opendkim/keys/example.com/2026q3
sudo opendkim-genkey -b 2048 -d example.com -D /etc/opendkim/keys/example.com/2026q3 -s 2026q3
sudo chown opendkim:opendkim /etc/opendkim/keys/example.com/2026q3/2026q3.private
sudo chmod 0600 /etc/opendkim/keys/example.com/2026q3/2026q3.private
opendkim-genkey creates a private file and a zone-file TXT fragment. Inspect the fragment rather than copying only part of its p= value. DNS consoles may display a long TXT record as adjacent quoted strings; receivers concatenate those strings, but multiple independent TXT records at the same selector name produce undefined DKIM results.
Private-key handling deserves a separate boundary. Do not paste the private key into tickets, chat, a public repository or a generic configuration backup. RFC 5863 prioritizes access control and auditing over frequent but weakly controlled rotation. If organizational policy requires recovery escrow, use an approved encrypted secret system with limited custodians; otherwise a lost key can be replaced through another controlled rotation.
Add the generated public key at 2026q3._domainkey.example.com. The existing selector, such as 2026q1._domainkey.example.com, remains unchanged and continues to validate current mail.
Query the authoritative service and more than one recursive resolver after publication. Replace the resolver addresses with those relevant to your users if policy requires different vantage points:
dig +short TXT 2026q3._domainkey.example.com @1.1.1.1
dig +short TXT 2026q3._domainkey.example.com @8.8.8.8
sudo opendkim-testkey -d example.com -s 2026q3 -k /etc/opendkim/keys/example.com/2026q3/2026q3.private -vvv
opendkim-testkey retrieves and parses the DNS key and, when given -k, compares it with the private key. Its Debian manual also notes that unsafe private-key permissions trigger a complaint. A successful DNS lookup without a key match is not a pass.
Wait until the new record is observable through the resolvers that matter. Lowering a TTL immediately before publication does not retroactively shorten a cached older TTL, and a fixed sleep does not prove that the correct value reached every authoritative server. Evidence from direct and recursive queries is stronger than a calendar promise.
OpenDKIM’s KeyTable maps a name to domain:selector:private-key, while SigningTable maps a sender pattern to that name. The OpenDKIM project README describes this separation. Keep both KeyTable entries during the overlap, but change only the intended sender mapping.
The following flat-file fragments illustrate the relationship; they are not a command to overwrite your files. Preserve the exact dataset prefix and wildcard convention already referenced by opendkim.conf.
# KeyTable
old._domainkey.example.com example.com:old:/etc/opendkim/keys/example.com/old.private
2026q3._domainkey.example.com example.com:2026q3:/etc/opendkim/keys/example.com/2026q3/2026q3.private
# SigningTable after the cutover
*@example.com 2026q3._domainkey.example.com
For multiple streams, change one narrow sender pattern or one signer instance first. A billing domain and marketing domain do not need to rotate in the same minute merely because they share a DNS zone. Independent cutovers make a failed receiver test attributable and keep rollback bounded.
OpenDKIM’s -n option parses the configuration and exits without starting the filter. Run it after staging the table change, then check whether the systemd unit supports reload:
sudo opendkim -n
systemctl show -p CanReload opendkim
When CanReload=yes, use the unit’s normal reload action. Otherwise schedule a monitored restart and confirm how Postfix handles a temporarily unavailable milter; an aggressive milter default can defer or reject submissions. Never improvise a restart during peak mail flow without knowing that policy.
After activation, watch the service log and queue rather than assuming a zero exit code proves signing:
sudo journalctl -u opendkim --since '-10 minutes' --no-pager
sudo postqueue -p
If mail was already delayed before the rotation, use Voxfor’s Postfix queue triage workflow to identify the owner and avoid bulk retries that mix an authentication change with a delivery incident.
Send a fresh message through the exact production submission path and inspect it at an external receiver. The DKIM-Signature must show the expected d=example.com, s=2026q3 and approved algorithm. Receiver results should show dkim=pass; when DKIM supplies the DMARC path, the signing domain must also align with the visible From domain under RFC 7489.
Selector rotation does not automatically change DMARC alignment because alignment compares domains, not selector names. A failure after cutover usually points to the wrong private key, malformed DNS, a signer that did not reload, a sender pattern that matched another KeyTable entry, or content modified after signing.
Capture one negative test where practical: submit from a sender pattern that should not use the new key, or verify that an unauthorized host cannot sign as the domain. The purpose is not to manufacture failed production mail; it is to prove the rotation did not broaden signing authority.
Cutover time is not retirement time. Messages signed just before the switch may be queued locally, deferred by a remote server or evaluated later in a downstream delivery path. Removing the old public key while those messages remain viable causes otherwise legitimate signatures to fail.
RFC 6376 does not prescribe one universal number of days. It tells signers to anticipate deferred verification and keep the old key available for the transition. Build the retirement timestamp from the last observed old signature, configured sender queue lifetime, longest accepted downstream delay and organizational policy. DNS TTL is evidence for record visibility, not a substitute for that mail-lifetime boundary.
Before retirement, search logs or message telemetry for the old selector, check the oldest queued message and confirm every planned stream now emits the new selector. A simple change record should contain:
Do not delete the old private key merely because a sample message passes with the new one. Quarantine it under the same restricted permissions until the rollback window closes. At retirement, remove the old selector from DNS or publish a revoked record with an empty p= according to policy, then securely dispose of the old private key after audit requirements are met. RFC 6376 treats missing and revoked keys as verification failures, although a revoked record can act as an explicit tombstone.
If the new path fails, restore the previous SigningTable mapping while both DNS records still exist, validate the configuration, reload or restart through the approved unit action, and send another external probe. Rollback changes the active signer; it does not require republishing the old public key because that key should never have been removed during cutover.
Only retire DNS after the new selector passes across the agreed receiver set and the old-signature boundary has elapsed. Teams that do not want to coordinate signer, DNS, queue and receiver evidence can assign mail and DNS operations to Voxfor under one change owner.
A recurring rotation job can reduce forgotten keys, but automation must preserve the same gates as a manual change. Safe orchestration creates a unique selector, stores the private key with restricted access, publishes the public record, polls authoritative and recursive DNS, compares public and private material, updates one signer mapping, sends a probe, and records receiver results. Deletion is a later state transition, not the final line of the activation script.
Fixed sleeps are weak automation. A control loop should advance only when the observed condition passes and should stop when evidence conflicts. For multi-domain fleets, rate-limit changes, retain per-domain state and avoid rotating every sender simultaneously; a DNS provider or signer bug should affect a small batch.
Algorithm migration is another reason to keep orchestration explicit. RFC 8463 standardizes Ed25519-SHA256 and allows RSA and Ed25519 signatures under different selectors during transition. Do not enable Ed25519 only because the RFC exists: confirm that the installed signer supports it and that important receiver paths verify it. RSA-SHA256 with a 2048-bit key remains the conservative OpenDKIM example in this guide.
Do not reuse a DKIM selector for a new key during normal rotation. RFC 6376 warns that reuse makes stale-key failures indistinguishable from forged signatures; assign the new key a new selector and publish both selector records during transition.
Keep the old selector until the last message signed with it has crossed the sender’s maximum queue lifetime, accepted downstream delay and verification policy. No universal grace period fits every mail system, so record the last old signature and derive retirement from real delivery boundaries.
Yes. Concurrent public keys under different selector names are the normal DKIM rollover mechanism. Publish the new record before signer cutover and leave the old record available for mail that still carries the old selector.
Routine same-algorithm key replacement normally needs one active signing selector plus two published public keys, not two signatures on every message. Dual signatures can support an algorithm transition, but they add verification and monitoring complexity and should be tested deliberately.
Changing only the selector does not break DMARC alignment. DKIM alignment compares the signing domain in d= with the visible From domain; verify both dkim=pass and dmarc=pass because a misrouted sender mapping can still change the signing domain.
Activation must wait. Check every authoritative server, inspect the exact TXT content and continue polling relevant recursive resolvers; a fixed delay is not proof that receivers can retrieve the matching public key.
Plaintext DKIM private keys do not belong in ordinary broad-access backups. Use restricted encrypted escrow only when policy requires recoverability, limit custodians and audit access; otherwise replace a lost key through a controlled new-selector rotation.
A compromised key turns maintenance into incident response. Stop unauthorized signing and revoke or remove the exposed public key according to containment policy even if some old-signed mail then fails; preserving graceful verification is secondary to ending abuse.
Successful rotation leaves evidence that another operator can audit: signer inventory, old and new selectors, key algorithms and sizes, DNS publication proof, first passing receiver sample, last old signature, rollback window, retirement time and private-key disposition. That ledger makes the next cycle repeatable without turning it into a blind timer.
DKIM’s selector mechanism already provides the safe control plane. Use it as designed: new name, parallel publication, proven cutover, delayed retirement. Explore Voxfor security operations library for adjacent domain and server controls that benefit from the same evidence-first change discipline.