Skip to content

Verify DKIM signing rate from Postfix logs

This is the critical caveat: Postfix does not perform DKIM signing or verification natively. DKIM operations are handled by a separate mail filter (milter) such as OpenDKIM or rspamd. Postfix invokes the milter via parameters like non_smtpd_milters and smtpd_milters, which point to a milter socket. Therefore, a “DKIM signing rate” is not found in Postfix delivery log lines; it lives in the milter’s own logs and in the DKIM-Signature headers added to your outbound messages.

Postfix
hands the message to the milter via non_smtpd_milters
Milter (OpenDKIM / rspamd)
signs the message, adds a DKIM-Signature header
Outbound mail
carries the signature; evidence is in the milter log + header
Postfix does not sign DKIM. A milter does, so the signing rate comes from the milter's logs and the DKIM-Signature header, not from Postfix delivery lines.

When a milter signs an outbound message, it logs the action to syslog (usually the mail facility), so the log lines appear in the same mail.log file as your Postfix records. The signing evidence comes from two places:

  1. Milter logs: OpenDKIM (RFC 6376 implementation) logs when it adds a DKIM-Signature header to a message. The exact log format depends on your milter configuration and syslog output, but it typically includes a queue ID and a note that a signature was added.
  2. Message headers: Every successfully signed outbound message receives a DKIM-Signature header. Reviewing a sample of your outbound mail (via mail command on your mail server, or checking a user’s sent folder if archived) shows the presence or absence of the header.

If a message goes unsigned, the milter may log a reason: a domain not in its signing configuration, a missing key, a temporary milter outage, or a mail path that bypasses the milter altogether.

Postfix forwards mail to a milter using two separate parameters:

  • non_smtpd_milters: Milter invoked for locally-submitted mail (e.g., from cron scripts, applications, or your own SMTP clients). This is where most outbound mail is signed.
  • smtpd_milters: Milter invoked for mail arriving via the SMTP daemon (inbound). Used for DKIM verification on inbound mail, and sometimes for signing if mail is relayed.

A typical non_smtpd_milters configuration points to a milter socket, e.g.:

non_smtpd_milters = unix:/var/run/opendkim/opendkim.sock

The socket can also use inet notation (e.g., inet:localhost:8891). OpenDKIM listens on this socket, receives mail from Postfix, and decides whether to sign it based on its configuration file (usually /etc/opendkim.conf).

OpenDKIM’s core signing configuration includes:

Domain example.com
Selector default
KeyFile /etc/opendkim/keys/default.private

This tells OpenDKIM to sign mail from example.com (the From: domain or envelope sender) using the default selector and the specified private key. A message from a domain not listed in OpenDKIM’s configuration will not be signed.

To compute the fraction of outbound mail that is signed:

  1. Identify outbound mail: Search Postfix logs for messages submitted via the non_smtpd path (local applications, cron, internal scripts, user SMTP submission). These are the messages that should be signed.
  2. Count signed vs unsigned: For each outbound message, check whether a DKIM-Signature header is present. This can be done by sampling a recent mail batch or querying archived mail headers.
  3. Calculate the rate: Divide the count of signed messages by the total count of outbound messages.
  4. Investigate gaps: If the rate is below 100%, check the milter logs for failures, and verify that all your outbound domains are in OpenDKIM’s configuration and have keys installed.

In practice:

  • A 100% signing rate means every outbound message received a DKIM-Signature. This is the goal for domains you operate.
  • A partial rate (e.g., 85%) suggests that some domains are not configured in OpenDKIM, or that some mail bypasses the milter (e.g., via certain relay routes or sendmail compatibility modes in Postfix).
  • A 0% or very low rate indicates that the milter is not being invoked, the socket is down, or no domains are configured.

Unsigned outbound mail from your domains weakens your email reputation and breaks DMARC alignment. DMARC policies often require either SPF or DKIM alignment to pass. When a message lacks a DKIM-Signature from your domain, DMARC can fail even if SPF passes, and receivers (especially large providers like Gmail and Microsoft) may quarantine or reject the mail. To confirm that a sample message carries a valid DKIM-Signature and aligns for DMARC, paste its headers into the Email Header Analyzer, which reports the SPF, DKIM, and DMARC result for that one message.

RFC 6376 (DKIM) defines the signing and verification process. A properly signed message includes a DKIM-Signature header that covers the mail headers and body, allowing receivers to verify the signature against your published DNS DKIM record (the public key).

If a message is not signed, typical reasons include:

  • Domain not in signing config: The message’s From domain is not listed in OpenDKIM’s Domain directives. Add the domain to OpenDKIM’s configuration and reload.
  • Missing or invalid key: The private key file for a domain/selector pair is not found, is unreadable, or is corrupted. Verify the KeyFile path and file permissions.
  • Milter socket unavailable: The milter is not running or the socket is not accessible to Postfix. Check that OpenDKIM is running and the socket path is correct.
  • Mail bypasses the milter: Some submission paths (e.g., certain relay settings or non-standard sendmail invocations) may not invoke the milter. Check Postfix configuration for alternate submit_cred filters or relay_transport settings.
  • Temporary milter failure: The milter crashed or was slow to respond. Postfix may default-allow the mail to pass unsigned. Check milter and syslog for errors.

Postfix Insights surfaces the DKIM signing rate and a breakdown of not-signed reasons directly in the /stats dashboard. Rather than manually cross-referencing milter logs and header samples, you see the signing coverage across your outbound volume at a glance. The tool parses Postfix and milter log entries from the same mail.log file, correlates them by queue ID, and aggregates the signing status over your chosen date range.

This makes it easy to:

  • Monitor signing health: Spot when signing rate drops, indicating a configuration or milter problem.
  • Identify unsigned domains: See which domains or selectors are not signed, and prioritize adding them to OpenDKIM.
  • Troubleshoot delivery: If mail from a domain is being rejected or deferred by receivers, cross-check the signing rate to rule out alignment issues.

To get started, see Quick start. For more on search and filtering, see the Postfix Insights GitHub repository.