2026.07 / SMTP AUTH 035
Fix “Relay Access Denied” in Docker Mailserver Safely
554 5.7.1 Relay access denied usually means Postfix is reachable and deliberately refused to forward a message. That is different from a timeout, a bad password, or a spam-folder problem. The refusal is an important anti-abuse control: an SMTP server should accept remote delivery for domains it owns, and should relay to other domains only for an authenticated or explicitly trusted client.
The wrong fix is to trust a wide Docker subnet, remove recipient restrictions, or add the whole internet to mynetworks. That can create an open relay. The right fix starts by identifying which SMTP contract the failed request was meant to use.
Do not “fix” relay denial by weakening relay policy. Prove that the recipient is local, or make the legitimate sending client authenticate on the submission service.
What the error actually tells you
Postfix separates receiving mail from relaying it. A remote mail server on port 25 may deliver to [email protected] if Docker Mailserver is configured to host example.com. A mail client logged in as that user may submit a message to [email protected] on port 587 or 465. An unauthenticated stranger must not be able to connect and forward arbitrary mail to an unrelated domain.
Postfix’s official relay-control documentation describes the normal permission boundary: relay mail from trusted networks, from SASL-authenticated clients, or to authorised relay destinations. A relay denial therefore points to one of four common situations:
- the client tried to send externally without successfully authenticating;
- the recipient domain was supposed to be local, but Docker Mailserver does not recognise it;
- a legitimate internal service was expected to use an explicitly trusted path, but its real source address is not in that narrow trust boundary;
- the request reached the wrong port or wrong server.
1. Capture the complete SMTP response and route
Record the timestamp, sender domain, recipient domain, server hostname, port, and whether the client attempted authentication. Redact usernames and never publish passwords, tokens, real server addresses, or full production logs. Then match the event in Docker Mailserver’s logs:
docker compose logs --since 15m mailserver
# If the service is not named mailserver, discover it first:
docker compose ps
Find the Postfix queue or connection lines around the failure. Useful evidence includes the client address, listener/service, sasl_username when authentication succeeded, recipient domain, and the exact reject text. The absence of sasl_username is a strong clue when a desktop client believed it had authenticated.
2. Decide whether this is delivery or submission
| Intent | Normal port | Expected permission |
|---|---|---|
| Another mail server delivers to a domain you host | 25 | Recipient domain/address is local; no client login required |
| A user’s mail app sends to an external recipient | 587 | STARTTLS, then SMTP AUTH |
| A user’s mail app uses implicit TLS submission | 465 | TLS from connection start, then SMTP AUTH |
| An internal application sends alerts | Usually 587 | Dedicated authenticated account preferred |
Docker Mailserver’s port guidance distinguishes SMTP transfer on 25 from authenticated message submission on 465/587. Do not point an ordinary mail app at port 25 merely because it accepts a TCP connection. Conversely, changing a client from 587 to 465 without changing STARTTLS to implicit TLS creates a protocol mismatch before relay policy is even evaluated.
3. Prove SMTP AUTH on the submission port
First inspect capabilities without entering credentials:
# Port 587 uses STARTTLS
openssl s_client -starttls smtp \
-connect mail.example.com:587 \
-servername mail.example.com -crlf
EHLO client.example.invalid
QUIT
The post-TLS EHLO response should advertise AUTH for a properly configured submission listener. Do not paste a base64-encoded password into a public terminal transcript—base64 is encoding, not encryption. Test the real account from a mail client or a purpose-built SMTP tester that can read credentials privately.
For a normal client, check all of these together:
- outgoing host is the mail hostname covered by the TLS certificate;
- port 587 uses STARTTLS, or port 465 uses implicit TLS;
- outgoing authentication is enabled rather than “none” or “use incoming only”;
- the login is the complete mailbox address expected by Docker Mailserver;
- the sender is allowed to use that identity under your configured policy.
Retest and inspect the server log. Success is not merely “AUTH appears in EHLO”; the specific transaction should show successful SASL authentication and then accept the external recipient.
4. If inbound delivery is denied, verify the local domain
Suppose an outside sender gets relay denial while mailing [email protected]. The server may not believe example.com is one of its destinations. Check public DNS and DMS account configuration separately:
dig +short MX example.com
dig +short A mail.example.com
dig +short AAAA mail.example.com
docker compose exec mailserver setup email list
docker compose exec mailserver setup alias list
The MX must name the intended mail host, and the address records must lead to the intended server. Inside DMS, a real account, alias, or supported catch-all configuration must establish the recipient path. After an account/configuration change, follow the current Docker Mailserver documentation for your pinned image and verify that the change loaded. Do not add the recipient domain to a generic relay list just to silence the error; that models the domain incorrectly and can produce loops or unsafe forwarding.
5. Inspect effective Postfix policy before editing it
Docker Mailserver builds Postfix configuration from defaults, environment variables, and supported overrides. Read the effective non-default policy:
docker compose exec mailserver postconf -n | grep -E \
'^(mynetworks|mydestination|relay_domains|smtpd_(relay|recipient)_restrictions|smtpd_sasl_auth_enable)\s*='
# Inspect the enabled master services without dumping secrets
docker compose exec mailserver postconf -M
A conventional relay restriction includes an authenticated/trusted permit followed by reject_unauth_destination. Exact generated settings vary by Docker Mailserver version, so compare the result with the current official docs and any deliberate local overrides. If an old override removed permit_sasl_authenticated, restore policy through DMS’s supported configuration mechanism rather than editing generated files inside the running container.
6. Treat mynetworks as a narrow exception
Some internal systems legitimately relay without SMTP AUTH, but broad trust is risky. Docker Mailserver warns that automatically trusting connected Docker networks can create an open relay in some network and IPv6 arrangements. Prefer a dedicated authenticated submission account for web applications, monitoring, and cron jobs.
If a legacy service truly cannot authenticate, isolate it on a private network, identify its stable source range, trust only the smallest required range, restrict sender identities where possible, and prove from an untrusted external host that relay is still denied. Never use 0.0.0.0/0, ::/0, an entire VPS provider range, or an unnecessarily broad LAN as a convenience fix.
7. Do not confuse an outbound relay host with inbound relay permission
A smarthost configuration answers a different question: where should Docker Mailserver send outbound messages after it has accepted them? DMS documents authenticated relay-host settings for networks where direct outbound port 25 is blocked or where a specialist sender is preferred. Configuring a smarthost does not automatically authorise an unauthenticated mail client to submit messages to DMS.
Keep the two authentication boundaries separate:
- mail client or application authenticates to Docker Mailserver;
- Docker Mailserver optionally authenticates to the upstream relay host.
A failure at the first boundary often produces relay denial during the client transaction. A failure at the second appears later in queue and delivery logs after DMS has already accepted the message.
8. Verify the fix without becoming an open relay
Run a small acceptance matrix after the change:
- From an external network, unauthenticated delivery to one valid local mailbox is accepted.
- From the same network, unauthenticated relay from an unrelated sender to an unrelated recipient is rejected.
- An authenticated user on 587 or 465 can submit to an external mailbox they control.
- A bad password is rejected and does not fall through to trusted relay.
- An invalid recipient at a hosted domain follows your intended reject policy.
- The accepted test message is queued, delivered, and passes the expected SPF/DKIM/DMARC checks.
Use harmless addresses you control. Do not run mass relay tests or send unsolicited messages. An external open-relay checker can be a useful second opinion, but the local transaction matrix and Postfix logs explain exactly which rule granted or denied access.
Common unsafe fixes to avoid
- Adding every Docker network to
mynetworks: container source addresses and published ports can make the resulting trust wider than expected. - Removing
reject_unauth_destination: disables a central relay guard instead of fixing authentication or local-domain configuration. - Using port 25 for all clients: mixes server transfer with user submission and often bypasses the intended TLS/AUTH service.
- Testing only login: successful IMAP authentication does not prove SMTP AUTH is enabled or used.
- Adding a hosted domain as a relay domain: can hide a missing mailbox/domain setup while creating the wrong routing model.
- Publishing logs or rendered Compose output: these may expose addresses, hashes, credentials, or infrastructure details.
Compact diagnosis checklist
- Capture the exact reject line, time, intended route, port, and redacted log event.
- Classify the request as inbound delivery, authenticated submission, internal application mail, or upstream smarthost delivery.
- For submission, verify the TLS mode, post-TLS AUTH capability, full account name, and successful SASL log line.
- For inbound mail, verify MX/address DNS and that DMS owns the recipient through an account or alias.
- Inspect effective relay restrictions and supported overrides.
- Prefer authentication over broad
mynetworkstrust. - Retest valid local delivery, authenticated external submission, and unauthenticated external relay denial.
- Confirm the accepted message actually leaves the queue and authenticates correctly at the recipient.
The authoritative references are Docker Mailserver’s port and submission guidance, its outbound relay-host documentation, and Postfix’s SMTP relay and access-control guide plus SASL guide. Use documentation matching your pinned DMS image because generated Postfix settings and supported override paths can change.