← Back home

2026.07 / EMAIL DELIVERABILITY 030

Docker Mailserver Emails Going to Spam: A Deliverability Checklist

Your Docker Mailserver container is healthy. SMTP accepts the message. The recipient server returns 250 OK. Then the email lands in spam.

That is not one problem with one switch. Delivery proves that a receiving server accepted the message; inbox placement is a later trust decision. The useful way to debug it is to work from machine identity and authentication outward, using the received message headers as evidence instead of changing DNS records at random.

Start with one controlled message, inspect what the recipient actually saw, and fix failed checks before trying to “improve reputation.”

First: distinguish rejection, deferral, and spam placement

These outcomes need different investigations:

Do not run dozens of test sends. Repetition from a new or misconfigured host adds noise and may make reputation signals worse.

1. Make the server identity internally consistent

A self-hosted mail server should have one stable, fully qualified hostname such as mail.example.com. Four views of that identity should agree:

  1. The server’s public address has a PTR (reverse-DNS) record returning mail.example.com.
  2. mail.example.com resolves forward to that same sending address.
  3. Postfix announces that hostname in its SMTP banner and EHLO.
  4. The SMTP TLS certificate is valid for that hostname.

PTR is normally configured in the VPS provider’s control panel, not at your ordinary DNS host. Do not invent a second PTR per mailbox domain: one server can send for several domains while keeping one machine identity.

# Forward lookup
      dig +short A mail.example.com

# Reverse lookup — use your own address, never a copied example
      dig +short -x <server-address>

# Check STARTTLS, certificate, and SMTP conversation
      openssl s_client -starttls smtp \
        -connect mail.example.com:25 \
        -servername mail.example.com

Google’s sender guidelines explicitly require valid forward and reverse DNS for sending domains or IPs. A PTR is not a substitute for message authentication, but a missing or generic PTR is a foundational fault.

2. Publish one accurate SPF policy

SPF says which systems may use a domain in the SMTP envelope sender. For a simple host whose MX is the only sender, the policy might be:

example.com.  TXT  "v=spf1 mx -all"

That is an example, not a value to copy blindly. If a website, helpdesk, newsletter provider, or transactional relay also sends as the domain, the policy must authorize the real mail flow. Publish one SPF record: two separate v=spf1 TXT records produce a permanent error rather than a stricter policy.

dig +short TXT example.com

SPF can pass yet fail DMARC alignment when the authenticated envelope domain differs from the address visible in From:. That distinction matters more than a green “SPF pass” badge.

3. Confirm DKIM is signing the message you sent

DKIM attaches a cryptographic signature to the message. Docker Mailserver can generate the key material, but three things still have to line up:

# If the signature says s=mail and d=example.com
dig +short TXT mail._domainkey.example.com

With multi-domain setups, generating a key is not always the same as enabling signing for that domain—especially when a custom Rspamd signing map already exists. Preserve working domain entries and add the new domain beside them. The Docker Mailserver project’s DKIM, DMARC, and SPF guide documents the current signing workflow.

4. Check DMARC alignment, not merely record presence

DMARC evaluates whether the visible From: domain aligns with a domain authenticated by SPF or DKIM. At least one aligned path must pass. A practical rollout begins with reporting rather than an immediate reject policy:

_dmarc.example.com. TXT \
  "v=DMARC1; p=none; rua=mailto:[email protected]"

Create the report mailbox or alias before publishing it, and remember that aggregate reports may contain metadata about your mail flows. After observing every legitimate sender and fixing alignment, move deliberately toward quarantine or reject. A stricter policy does not repair broken alignment.

Google requires SPF or DKIM for all senders to personal Gmail accounts and imposes SPF, DKIM, DMARC, alignment, and additional requirements on bulk senders. Even a low-volume personal server benefits from deploying all three correctly.

5. Read the recipient’s Authentication-Results header

In Gmail, use Show original. Other clients usually expose “view source” or “view message details.” Look for a block shaped like this:

Authentication-Results: recipient.example;
  spf=pass smtp.mailfrom=example.com;
  dkim=pass header.d=example.com;
  dmarc=pass header.from=example.com

The recipient’s result is more useful than a DNS checker alone because it evaluates the message that really arrived. Diagnose each failure literally:

6. Inspect Docker Mailserver and Postfix evidence

Use your actual Compose service or container name. Keep message IDs and remote SMTP responses; redact addresses before sharing logs publicly.

# Recent mail logs
docker logs --since 30m mailserver

# Queue summary
docker exec mailserver postqueue -p

# Confirm the effective hostname
docker exec mailserver postconf myhostname

# List Docker Mailserver accounts
docker exec mailserver setup email list

A log line showing status=sent and a remote 250 response confirms handoff, not inbox placement. A queue full of deferred mail points back to connectivity, DNS, rate, or remote-policy errors before content filtering.

7. Check reputation without chasing magic scores

A new VPS address has little or no sending history. A recycled address may have bad history. Authentication proves authorization; it does not guarantee reputation.

Google advises senders to keep user-reported spam rates below 0.1% and avoid ever reaching 0.3%. For a personal server, the simpler rule is to send only wanted mail and make unsubscribing easy wherever messages are subscription-based.

8. Use a boring controlled test message

Test one variable at a time with a message that resembles legitimate correspondence:

Content matters, but rewriting copy before SPF, DKIM, DMARC, and PTR pass is debugging in the wrong order. Likewise, marking your own test as “not spam” may train one mailbox without proving that the infrastructure is correct.

A compact order of operations

  1. Stop repeated tests and save one recipient message source.
  2. Confirm the SMTP result: rejected, deferred, or accepted.
  3. Verify PTR → hostname → forward DNS, EHLO, and TLS certificate.
  4. Verify the single SPF policy matches every legitimate sender.
  5. Confirm the received message has a valid DKIM signature.
  6. Confirm DMARC passes through SPF or DKIM alignment.
  7. Inspect Postfix logs and the queue using the message ID.
  8. Only then assess address/domain reputation and message construction.
  9. Send one new controlled test and compare headers.

Self-hosted email deliverability is never guaranteed, and inbox algorithms are intentionally not fully public. But the investigation does not have to be mystical. Build a coherent server identity, authenticate the exact message, read the receiving system’s verdict, and change only the layer the evidence says is broken.