← Back home

2026.08 / IMAP login 045

Docker Mailserver IMAP Login Failed? Test Dovecot and Port 993

Your mail client can no longer open a Docker Mailserver mailbox. It may loop on the password prompt, say “login failed”, or report that it cannot connect to the IMAP server. Dovecot may log auth failed, but a generic client message does not prove the password is wrong.

An IMAP login crosses several distinct boundaries: DNS reaches the intended host, TCP reaches the published port, TLS presents the expected certificate, Dovecot offers IMAP, the client sends the correct full mailbox identity, the active account provisioner verifies it, and Dovecot opens the user’s mail storage. Test those boundaries in order instead of repeatedly resetting credentials.

Run one controlled login while watching the matching private server event. Never publish passwords, authentication exchanges, real addresses, complete logs, account hashes, or server IPs.

First: classify the symptom

Observed resultInvestigate first
Timeout or connection refusedDNS, firewall, Docker port publishing, or Dovecot listener
Certificate or TLS handshake errorHostname, certificate mount, TLS mode, or stale endpoint
Server greets, then rejects loginFull username, password, account source, or authentication policy
Temporary/internal authentication failureDovecot auth service, configuration, permissions, or host capacity
Login succeeds but mailbox cannot openMail storage path, ownership, indexes, quota, or disk capacity
One network fails while another worksFail2Ban, source filtering, IPv6 path, or split DNS

This guide is for mailbox access through IMAP. If sending fails on port 587 or 465 while reading still works, use the separate Docker Mailserver SMTP authentication guide.

1. Verify the client is using the intended IMAP service

Docker Mailserver’s current documentation recommends IMAPS on port 993. It uses implicit TLS: encryption begins immediately when the connection opens. Port 143 uses IMAP with STARTTLS and is generally retained for compatibility. Do not configure STARTTLS on 993 or implicit “SSL/TLS” on 143.

Check the client settings:

Do not use the website hostname merely because it shares the same domain. Mail DNS and web proxying can lead to different services.

2. Test TCP, TLS, and the public certificate without a password

From a network outside the VPS, inspect the IMAPS handshake:

openssl s_client \
  -connect mail.example.com:993 \
  -servername mail.example.com \
  -verify_return_error </dev/null

A useful result establishes a connection, presents a certificate valid for the requested mail hostname, and shows a successful verification result. It does not prove credentials work, but it removes DNS, routing, port publication, and most TLS ambiguity.

If the connection times out, compare public A and AAAA answers, provider firewall rules, host firewall rules, and Compose port publication. A client may prefer a broken IPv6 address while your IPv4 test succeeds. If the certificate is old, follow the Docker Mailserver certificate renewal path before changing account data.

3. Match one login attempt to one Dovecot event

Watch only a short recent window, make one login attempt, then stop:

docker compose ps

docker compose logs --since 5m --follow mailserver

Use the actual Compose service name. Keep output private because it can expose mailbox names, source addresses, internal paths, and session details. The distinction matters:

Temporarily increasing Docker Mailserver’s documented LOG_LEVEL can add evidence, but treat debug or trace as a short diagnostic change. Revert it after the controlled test and review verbose output locally.

4. Confirm the account exists in the active provisioner

With Docker Mailserver’s default file provisioner, list accounts through the supported setup CLI:

docker compose exec mailserver setup email list

Confirm that the exact full address exists. Do not print or edit the underlying account file directly; it contains password hashes. If the deployment uses LDAP or OAuth2, test that configured identity source instead. Repairing the file provisioner cannot fix an LDAP mapping or OAuth token flow.

Aliases are delivery addresses, not automatically separate login accounts. A message can arrive through an alias while IMAP still requires the real provisioned mailbox identity.

5. Test authentication inside the container

Dovecot’s official diagnostic interface can test the authentication backend without involving public networking. Use an interactive prompt where supported so the password does not become a shell argument or enter history:

docker compose exec mailserver \
  doveadm auth test [email protected]

Enter the test secret only at the prompt. If your pinned Dovecot version requires different syntax, read its local help with doveadm auth test --help and follow that version rather than placing a password on the command line.

Do not paste a password into docker compose exec ... doveadm auth test user password. Command arguments can be retained in shell history or exposed to local process inspection.

6. Reset a password only after proving a credential fault

For the file provisioner, Docker Mailserver’s setup CLI can update one account interactively:

docker compose exec mailserver \
  setup email update [email protected]

Use a unique password, enter it at the prompt, and update one client first. Remove stale saved credentials from the client’s password manager if it keeps retrying the old value. Then repeat one internal authentication test and one external IMAP login.

If many devices began failing at the same time without a planned change, preserve logs and consider compromise or an account-source outage before rotating everything. A password reset is not a substitute for understanding why authentication changed.

7. Inspect effective Dovecot service and listener state

If transport works but Dovecot reports internal errors, inspect the effective configuration and running processes privately:

docker compose exec mailserver doveconf -n

docker compose exec mailserver doveadm service status

docker compose exec mailserver ss -lntp

Look for the enabled IMAP protocol, expected listeners, authentication configuration, and deliberate overrides. doveconf -n can reveal internal paths and settings, so do not publish it unredacted.

Make permanent fixes through Docker Mailserver’s supported environment variables and mounted configuration, not by editing generated files inside the running container. An in-container edit can disappear on recreation and leave Git or Compose different from production.

8. Separate authentication from mailbox-storage failure

A successful auth event followed by a disconnect or mailbox error means the password worked. Check volume capacity and Dovecot’s view of the user:

docker compose exec mailserver df -h

docker compose exec mailserver df -i

docker compose exec mailserver \
  doveadm user [email protected]

Review the user lookup privately because it can expose paths and identifiers. A full filesystem, exhausted inodes, wrong mount, damaged permissions after a manual restore, or unsupported Maildir edits can prevent mailbox access after successful login.

Do not recursively change ownership or delete Dovecot indexes as a first response. Compare the persistent mounts with the intended Compose configuration and the restore procedure. If logs show a quota-specific failure, use the mailbox quota guide to distinguish personal limits from volume capacity.

9. Check Fail2Ban without weakening it

Repeated password prompts can cause a legitimate client address to be banned. Inspect Docker Mailserver’s Fail2Ban status:

docker compose exec mailserver setup fail2ban status

If the source is listed, stop every device still retrying stale credentials, confirm the attempts are yours, and use the version-appropriate narrow unban action. Do not disable Fail2Ban globally or allowlist a broad public range. Unfamiliar repeated login failures are a security signal: preserve relevant evidence, rotate the affected credential if appropriate, and keep rate controls enabled.

10. Prove recovery at every boundary

  1. Confirm public port 993 presents the correct hostname certificate.
  2. Confirm one internal doveadm auth test succeeds.
  3. Confirm one external client login creates a matching successful Dovecot event.
  4. Open INBOX and one existing folder to prove storage access, not just authentication.
  5. Send a harmless message to the mailbox and confirm it appears.
  6. Move or flag a test message and confirm the change survives reconnect.
  7. Confirm no client continues stale retries and no fresh ban appears.

This small matrix prevents a false fix where the password is accepted but the mailbox volume remains unreadable, or where one network works while the user’s normal source is still banned.

Compact diagnosis order

  1. Classify timeout, TLS error, credential rejection, internal auth failure, or post-login storage fault.
  2. Verify hostname, implicit TLS, and public certificate on port 993.
  3. Match one client attempt to one private Dovecot event.
  4. Confirm the full mailbox account exists in the active provisioner.
  5. Run one interactive internal authentication test.
  6. Reset one password only if evidence identifies a credential fault.
  7. Inspect Dovecot services, listeners, disk, inodes, and user lookup as needed.
  8. Check Fail2Ban without broadly weakening protection.
  9. Verify login, mailbox reads, a fresh delivery, and a persistent mailbox change.

The authoritative references are Docker Mailserver’s port and TLS guidance, its file-provisioner setup CLI documentation, its debugging guide, and Dovecot’s official doveadm-auth manual and protocol testing guide. Match every command to the Docker Mailserver and Dovecot versions you actually run.