Era Host hosting
EraHost – Free Domain, Cheap Hosting!
Client Area
Support 24/7
Menu

dovecot_virtual_delivery in Dovecot: What It Means and How to Troubleshoot It

27 min read
15.11.2025

You open the Exim log while investigating a missing message and find a line containing T=dovecot_virtual_delivery. The name looks like a Dovecot option, so the first instinct is often to search dovecot.conf, restart Dovecot, or look for a setting called dovecot_virtual_delivery.

That usually sends the investigation in the wrong direction. dovecot_virtual_delivery is commonly an Exim transport name used when Exim hands mail for a virtual mailbox to Dovecot. The transport may invoke Dovecot LDA, communicate with Dovecot over LMTP, or be generated differently by a hosting control panel. The name alone does not tell you which delivery mechanism is active. For the wider server-side context around routing, delivery and mail service diagnostics, see the mail server on a VPS guide.

The useful question is not whether dovecot_virtual_delivery appears in the log. The useful question is what happened after Exim selected it. A successful 250 response means something very different from a defer, an unknown-user response, an LMTP connection failure, a quota error, or a filesystem problem.

The fastest troubleshooting route is to trace one recipient from Exim routing to Dovecot user lookup and finally to mailbox storage. If Exim routes the address incorrectly, Dovecot is not the problem yet. If routing is correct but Dovecot cannot resolve the user, there is no reason to touch mailbox permissions. Each successful check eliminates an entire layer.

Why does Exim show dovecot_virtual_delivery in the mail log?

dovecot_virtual_delivery in an Exim log normally identifies the transport selected for delivery to a virtual mailbox. Seeing the name by itself does not indicate a Dovecot failure.

A successful local delivery can contain fields similar to these:

R=virtual_user T=dovecot_virtual_delivery C="250 2.0.0 ... Saved"

Three fields matter. R= identifies the router that decided where the recipient should go. T= identifies the transport selected for delivery. C=, when present, records a response from the next component in the delivery path. Here the useful evidence is the positive 250 response and Saved, not the unfamiliar transport name.

A failing transaction can use exactly the same transport:

R=virtual_user T=dovecot_virtual_delivery defer (-1): LMTP connection closed after end of data

The transport name has not changed. The result has. Troubleshooting should start with the result.

When a user reports that a message disappeared, find the complete history of one message rather than copying the first line that contains dovecot_virtual_delivery. On many cPanel systems the Exim log is /var/log/exim_mainlog; other distributions and mail stacks can use a different path.

exigrep MESSAGE-ID /var/log/exim_mainlog

If exigrep is unavailable, search the appropriate Exim log with grep. Follow the same message ID from acceptance to routing, delivery and completion. Exim's familiar log markers also help: <= normally marks message arrival, => a successful delivery, == a deferred delivery, and ** a failed delivery. Exact log detail varies with the configuration, but those markers make it much easier to distinguish “message accepted” from “message stored in the mailbox.”

Diagnostic rule: the words after T=dovecot_virtual_delivery usually tell you more than the transport name itself.

Is dovecot_virtual_delivery actually a Dovecot setting?

dovecot_virtual_delivery is normally an Exim transport label, not a standalone Dovecot configuration option. That is why searching doveconf -n or files under /etc/dovecot/ may return nothing with that exact name.

Exim first routes the recipient, then assigns a transport. That transport can invoke Dovecot LDA, connect to Dovecot LMTP, or use another locally defined delivery method. Dovecot handles the mailbox side after that handoff.

SMTP reception
Exim router
Exim transport
Dovecot LDA or LMTP
Dovecot userdb
Mailbox storage

Start with Exim's effective configuration:

exim -bP transports

If a transport named dovecot_virtual_delivery exists, inspect it directly:

exim -bP transport dovecot_virtual_delivery

An illustrative LDA-style result could contain something conceptually similar to:

dovecot_virtual_delivery:
  driver = pipe
  command = /path/to/dovecot-lda ...

The decisive lines are driver and the delivery command. If the driver is pipe and the command invokes dovecot-lda, you are looking at an LDA path. Check the actual command and execution context rather than searching Dovecot for a setting with the transport's name.

An LMTP-based configuration looks different. The effective Exim configuration may identify an LMTP transport or another transport definition that points to a Dovecot LMTP endpoint. The exact syntax depends on the Exim build and the server's configuration, so do not force an example from another installation onto your own.

Then inspect Dovecot separately:

doveconf -n

If Exim shows dovecot_virtual_delivery while doveconf -n does not, nothing is missing. They are different configuration namespaces.

What to inspect: if the Exim transport uses driver = pipe, inspect the command. If delivery uses LMTP, inspect the LMTP service and endpoint. If the transport name does not exist at all, stop assuming the tutorial or log sample you found matches this server and search the effective Exim configuration for the transport actually selected by exim -bt.

Transport names are also arbitrary labels. An administrator or control panel can call a transport virtual_mail, dovecot_lmtp, local_mailboxes, or something else. The implementation matters; the label does not define it.

How does a message reach a virtual mailbox through dovecot_virtual_delivery?

A message can be accepted successfully over SMTP and still fail before it reaches the mailbox. SMTP acceptance, recipient routing and mailbox storage are separate stages, so the investigation should follow the same path as the message.

Stage Component What to check Typical evidence
Message acceptance Exim Was the message accepted? Incoming entry such as <=
Recipient routing Exim Which router accepted the address? R=virtual_user or another router
Transport selection Exim Which delivery transport was assigned? T=dovecot_virtual_delivery
User lookup Dovecot Can Dovecot resolve the mailbox? doveadm user
Mailbox delivery Dovecot Can Dovecot store the message? Dovecot log, quota and storage checks
Completion Exim Did the delivery finish? Success, defer, reject or final completion

Suppose Exim accepts a message for alice@example.com. A router checks whether example.com is handled locally and whether Alice matches a virtual mailbox, alias, redirect, local system user or another routing rule. If a virtual-user router accepts the address, it assigns a delivery transport.

The transport passes the envelope and message to the configured Dovecot delivery mechanism. Dovecot may still need to resolve the user through userdb, determine UID/GID and mailbox location, enforce quota, execute Sieve rules, update indexes and write data to Maildir, mdbox or another configured storage backend.

An incoming <= line therefore does not prove that a message reached the mailbox. It proves that Exim accepted the message. If the local delivery later returns a temporary error, Exim can keep the message queued and retry according to its retry configuration.

The useful breakpoint is the first stage that fails. If routing is wrong, stay in Exim. If routing is correct but Dovecot rejects the user, move to userdb. If the user resolves but LMTP cannot be reached, inspect the service and socket. Only after those stages succeed does mailbox storage become the next suspect.

Is dovecot_virtual_delivery using LDA or LMTP on this server?

You cannot determine LDA versus LMTP from the name dovecot_virtual_delivery. Inspect the Exim transport itself. Older or custom configurations may invoke dovecot-lda through a pipe, while many current installations use the Dovecot LMTP service.

How to recognize an LDA pipe transport

An LDA setup normally starts the Dovecot Local Delivery Agent as a short-running process for delivery. The Exim transport commonly uses the pipe driver and contains a command invoking dovecot-lda.

An illustrative configuration may resemble:

dovecot_virtual_delivery:
  driver = pipe
  command = /path/to/dovecot-lda -d $local_part@$domain -f $sender_address
  message_prefix =
  message_suffix =

The path above is intentionally generic. Package layouts differ, so copying /usr/lib/dovecot/dovecot-lda, /usr/local/libexec/dovecot/dovecot-lda, or another path from a different server is not a safe configuration method.

If the active transport uses driver = pipe and starts dovecot-lda, troubleshoot execution identity, user lookup, command arguments, filesystem access and the delivery process exit status.

How to recognize LMTP delivery

LMTP uses a running Dovecot service instead of starting a new LDA process for every delivery. When Exim and Dovecot share a server, a UNIX socket is a common handoff. TCP LMTP is also possible.

A simplified Exim-side example can resemble:

dovecot_lmtp:
  driver = lmtp
  socket = /path/to/dovecot/lmtp

Check the active Exim and Dovecot configuration instead of assuming that path:

exim -bV
doveconf -n
ss -lx
ss -ltnp

If a UNIX socket is involved, confirming that it exists is only the first check. Inspect the socket and every parent directory that Exim needs to traverse:

stat /path/to/dovecot/lmtp
namei -l /path/to/dovecot/lmtp

A socket can be present and still unusable because its owner, group or mode does not permit the Exim process to connect. That situation looks very different from “Dovecot LMTP is not listening,” even though both can surface as a handoff failure.

Why the transport name alone is not enough

Exim transport names are configuration labels. Two servers can both log T=dovecot_virtual_delivery while using different internals. One can pipe a message to dovecot-lda; another can use LMTP; a hosting panel can generate its own transport around either mechanism.

Criterion Dovecot LDA Dovecot LMTP
Execution model Short-running delivery process Long-running Dovecot service
Typical Exim side Pipe transport LMTP transport or connection
Useful clue Command invokes dovecot-lda Socket, LMTP session or LMTP response
Failure evidence Process output or exit status LMTP response, socket or session error
Current Dovecot guidance Supported Recommended for most installations

A perfectly valid old LDA tutorial can be the wrong fix for a server that already delivers through LMTP. Identify the plumbing first.

Why do virtual users use dovecot_virtual_delivery while another recipient uses dovecot_delivery?

Two addresses on the same server can legitimately follow different Exim routers and transports. A virtual mailbox such as sales@example.com does not have to correspond to a normal Unix account, while a hosting account owner or system user may be routed through another local-delivery path. If you are configuring the mailbox structure rather than diagnosing an existing one, the separate mailbox and user setup guide covers account creation and user layout in more detail.

Compare the routing before comparing Dovecot settings:

exim -bt mailbox@example.com
exim -bt account-owner@example.com

The exact output varies, but the first result may conceptually show a virtual-user route:

mailbox@example.com
  router = virtual_user
  transport = dovecot_virtual_delivery

A system account can legitimately produce a different decision:

account-owner@example.com
  router = localuser
  transport = dovecot_delivery

Those names are illustrative rather than universal. The useful comparison is the router and transport selected for each address.

Aliases and forwarders can bypass the expected mailbox transport

A third address may never reach Dovecot local delivery at all:

sales@example.com
  router = virtual_alias
  redirect = another@example.net

If the address is an alias or forwarder, debugging the virtual mailbox path is premature. Exim has already made a different routing decision.

Default addresses and catch-all rules can create the same confusion. A sender sees an address under a local domain, but Exim may route the recipient into a hosting account, redirect it to another mailbox, or reject it because no valid mailbox exists.

A local domain does not mean every recipient under that domain follows the same delivery path.

If one mailbox fails while other mailboxes under the same domain work, compare exim -bt for the broken mailbox and a known-good mailbox. If the router differs, stay on the Exim side. Dovecot storage is not the next check.

How can you trace one recipient before changing the mail configuration?

Before editing Exim or Dovecot, trace one affected recipient and one real message from routing to mailbox delivery. The goal is not to run every mail command you know. The goal is to find the first disagreement.

Trace the address with Exim

exim -bt user@example.com

Record the router and transport. If Exim sends the address through an alias, redirect, wrong local router or unexpected transport, stop there. Changing Dovecot permissions cannot fix a recipient that never reaches the intended Dovecot delivery path.

-bt is a routing test, not a complete delivery simulation. Conditions that depend on message data or runtime context can behave differently during a real delivery. Use it to establish the expected route, then verify that route with a real message.

Confirm that Dovecot resolves the same recipient

doveadm user user@example.com

An illustrative successful lookup can resemble:

field   value
uid     5000
gid     5000
home    /var/vmail/example.com/user

The exact fields and formatting depend on the configured userdb. The point is that Dovecot recognizes the same recipient Exim just routed.

Now consider the opposite result. Exim routes user@example.com through dovecot_virtual_delivery, but doveadm user user@example.com reports that the user cannot be found. Stop there.

That rules out mailbox permissions as the first problem. Exim and Dovecot disagree about whether the mailbox exists, so investigate the account source, userdb mapping, domain handling or panel-generated mailbox data before touching the filesystem.

Trace one real message ID

Take a real message ID from Exim and display its related log events:

exigrep MESSAGE-ID /var/log/exim_mainlog

A healthy path will normally contain evidence of acceptance, routing, delivery and eventual completion. A temporary local delivery failure will instead show a defer and leave the message available for another queue attempt.

If the system keeps per-message spool logs, the Exim message log can also help with an already queued message:

exim -Mvl MESSAGE-ID

Availability and detail depend on the Exim build and spool setup, but when present it gives you a message-specific delivery history without searching the entire main log.

Two common diagnostic branches

Exim route is correct, but Dovecot says unknown user. Investigate userdb and account mapping. Do not touch mailbox permissions yet.

Exim route is correct, Dovecot resolves the user, but the log shows an LMTP failure. User mapping has passed. Move to the LMTP service, socket permissions and the Dovecot log at the same timestamp.

  1. Run exim -bt user@example.com and record the router and transport.
  2. Run doveadm user user@example.com and confirm Dovecot resolves the same recipient.
  3. Trace one real message ID through the Exim log.
  4. Match the failure timestamp with the Dovecot log or journal used on that server.
  5. Continue only from the first stage that failed.

Route first, restart later. A restart can clear a temporary symptom while hiding the reason it happened.

What does a successful dovecot_virtual_delivery log entry look like?

A successful dovecot_virtual_delivery path has more than one useful line. Read the message lifecycle rather than treating T=dovecot_virtual_delivery as a standalone status.

A complete successful path

A simplified Exim lifecycle can look conceptually like this:

2026-09-14 12:00:01 MESSAGE-ID <= sender@example.net ...
2026-09-14 12:00:02 MESSAGE-ID => user@example.com R=virtual_user T=dovecot_virtual_delivery C="250 2.0.0 ... Saved"
2026-09-14 12:00:02 MESSAGE-ID Completed

The timestamps and fields above are illustrative. What matters is the sequence.

  • <= shows that Exim accepted the message.
  • => shows a successful delivery attempt to the recipient.
  • R=virtual_user tells you which router selected the address.
  • T=dovecot_virtual_delivery identifies the transport.
  • 250 ... Saved indicates that the next delivery component accepted the message.
  • Completed shows that Exim finished processing that message once all required deliveries were done.

When those pieces line up, the local transport is not the first suspect anymore. If the user still cannot see the message, check the final mailbox folder, Sieve rules, aliases and the mail client.

What a temporary failure looks like

A temporary failure changes the lifecycle:

2026-09-14 12:00:01 MESSAGE-ID <= sender@example.net ...
2026-09-14 12:00:02 MESSAGE-ID == user@example.com R=virtual_user T=dovecot_virtual_delivery defer (-1): LMTP connection closed after end of data

There is no successful recipient delivery here. Exim has accepted the message, but local delivery was deferred. Depending on the retry configuration, the message can stay in the queue and be attempted again later.

Check the queue:

exim -bp

If the root cause has already been fixed, you usually do not need to delete and resend the original message. Exim's queue runner can retry it. For a specific queued message, an administrator can trigger another delivery attempt after confirming the fault is resolved:

exim -M MESSAGE-ID

Use that on the specific message you are testing, not as a substitute for fixing the error. Forcing repeated retries while LMTP, storage or quota is still broken only produces more log noise.

Temporary defer and permanent failure are different diagnoses

A deferred delivery means Exim expects that retrying may eventually succeed. A permanent delivery failure means the recipient or delivery cannot be completed under the current conditions and normally follows a different handling path. In Exim logs, == and ** are useful visual clues for that distinction.

A successful delivery still does not prove that the message landed in INBOX. It proves that the configured local-delivery path accepted it. Folder placement is a separate question.

Which dovecot_virtual_delivery errors point to Dovecot, the mailbox, or Exim?

dovecot_virtual_delivery failures have to be classified by the error that follows the transport name. The same Exim transport can expose failures from the LMTP service, Dovecot userdb, quota handling, filesystem permissions or the mailbox storage backend.

Log symptom Likely layer First check
LMTP socket unavailable Dovecot service or socket Listener, socket path and permissions
Unknown user Routing or Dovecot userdb exim -bt and doveadm user
Permission denied Filesystem, UID or GID Resolved mailbox identity and path ownership
Quota exceeded Dovecot or account quota Mailbox quota and hosting limits
No space left Filesystem df -h and df -i
LMTP connection closed after DATA Dovecot, mailbox backend or service Matching Dovecot-side log entry
Successful save but message missing Sieve, alias or mailbox folder Filters and final mailbox destination

LMTP socket or connection failures

If Exim cannot connect to the configured LMTP socket, confirm that Dovecot is running, LMTP is enabled, the endpoint exists and Exim can access it. Useful checks include:

doveconf -n
ss -lx
systemctl status dovecot
journalctl -u dovecot --since "10 minutes ago"

systemctl and journalctl apply to systemd-based installations; another init or logging setup requires the equivalent service and log checks.

A UNIX socket can exist but still reject access because of its owner, group, mode or the permissions of a parent directory:

stat /path/to/dovecot/lmtp
namei -l /path/to/dovecot/lmtp

If Dovecot is listening but Exim cannot reach the socket, compare the socket permissions with the identity under which the Exim delivery process accesses it. Do not simply make the socket world-writable.

An error such as:

T=dovecot_virtual_delivery defer (-1): LMTP connection closed after end of data

does not prove that the socket itself is broken. Dovecot may accept the LMTP connection and terminate the transaction later after a mailbox-side failure. Read the corresponding Dovecot event before changing socket settings.

Unknown user or userdb lookup failures

If Dovecot rejects the recipient as unknown, compare Exim routing with Dovecot lookup:

exim -bt user@example.com
doveadm user user@example.com

If Exim accepts the address through a virtual-user router but Dovecot cannot resolve it, inspect the account source used by each component. SQL, LDAP, passwd-style files and panel-generated data can all create a mismatch where one side knows the account and the other side does not. If the issue turns out to be mailbox/account provisioning rather than transport delivery, the mailbox and user setup guide is the closer troubleshooting path.

Do not jump to mailbox ownership. Dovecot cannot write to a mailbox it cannot resolve.

Mailbox storage and permission failures

A permission error usually means delivery reached the storage layer but the process cannot access a required path under the identity Dovecot expects.

First determine the resolved user:

doveadm user user@example.com

Then inspect the mailbox path:

namei -l /path/to/mailbox
stat /path/to/mailbox
ls -ld /path/to/mailbox

chmod -R 777 is not a diagnostic method. It can hide the ownership problem, expose mailbox data and create a second fault. Compare the UID/GID Dovecot expects with the actual owner and permissions, then correct the specific mismatch.

Quota-related delivery failures

A mailbox quota failure and a full server filesystem are different faults. Check both.

If Dovecot quota support is configured, a useful command can be:

doveadm quota get -u user@example.com

Then verify filesystem capacity:

df -h
df -i

df -h checks storage blocks. df -i checks inodes. A mail filesystem can have gigabytes free and still reject new files because it has no free inodes.

Mailbox corruption or backend-specific failures

If Dovecot logs report corruption in mdbox, Maildir indexes or another mailbox backend, handle the error according to that backend. “Delete the indexes” is not a universal repair.

Some index data can be rebuilt; mailbox data files are a different matter. If the log points to actual mailbox data corruption, preserve a backup and use the Dovecot recovery procedure appropriate to the storage format. A command such as doveadm force-resync can be relevant to specific mailbox or index problems, but the mailbox format and the exact error should justify it first.

One mailbox fails, or every virtual mailbox fails?

This is one of the quickest ways to reduce the search area. If only user@example.com fails while other virtual mailboxes on the same server continue receiving mail, start with recipient-specific layers:

  • the Exim route for that address;
  • Dovecot userdb lookup;
  • mailbox path and ownership;
  • per-user quota;
  • per-mailbox corruption or Sieve rules.

If many or all virtual mailboxes begin failing at the same time, do not inspect twenty individual Maildir owners first. Check shared components:

  • Dovecot service state;
  • the LMTP listener or socket;
  • socket permissions;
  • the filesystem hosting mailboxes;
  • free space and inodes;
  • shared SQL/LDAP/userdb backends;
  • a common mailbox storage backend or mount.

If one mailbox is broken, think local. If every mailbox is broken, think shared layer first.

What happens to messages that were already deferred?

Fixing Dovecot does not make the old Exim log entries disappear. Messages that received a temporary delivery error can remain queued until Exim retries them or until their retry lifetime is exhausted according to the active configuration.

Check the queue after repairing the cause:

exim -bp

Then inspect a specific queued message if necessary:

exim -Mvl MESSAGE-ID

If the message is still queued and the service is now healthy, allow the normal queue runner to retry it or trigger a deliberate retry for that message. Do not remove queued mail merely because the first delivery attempt failed.

Read the delivery line from the end backward, then correlate the failure with the Dovecot event at the same time. The transport name is only the middle of the story.

How do you verify Dovecot userdb, mailbox paths, UID/GID and storage?

If Exim selects the expected transport and the LDA or LMTP handoff works, verify that Dovecot resolves the mailbox to the correct identity and storage location.

Compare Dovecot's user data with the filesystem

Start with:

doveadm user user@example.com

An illustrative result might contain:

uid     5000
gid     5000
home    /var/vmail/example.com/user

The exact output depends on userdb. Now compare the resolved path with the filesystem:

stat /var/vmail/example.com/user
namei -l /var/vmail/example.com/user

Suppose Dovecot resolves UID 5000 and GID 5000, but stat shows that the mailbox tree is unexpectedly owned by root:root and does not grant the required access to the mail user. That is a concrete mismatch. Correct the ownership or permission problem according to the intended virtual-mail design.

Now change the scenario. Dovecot returns the expected UID/GID, the mailbox path is owned correctly, and every parent directory can be traversed. Permissions are no longer the leading suspect.

Stop changing them.

Free disk space does not rule out inode exhaustion

Check both blocks and inodes on the filesystem that actually stores mail:

df -h /var/vmail
df -i /var/vmail

A server can show plenty of free capacity in df -h while df -i is at or near exhaustion. Maildir-style storage can create large numbers of files, so inode exhaustion can block new message files even when the disk still has gigabytes available.

In that case, changing UID/GID does nothing. The filesystem capacity problem is elsewhere.

Check whether the filesystem became read-only

An I/O or filesystem fault can leave ownership and free-space checks looking reasonable while writes still fail. Inspect mount state and the system logs appropriate to the server when Dovecot reports read-only filesystem or low-level I/O errors.

This matters especially when many unrelated mailboxes begin failing at the same time. A common filesystem or mount problem fits that symptom much better than twenty simultaneous ownership mistakes.

Check quota only after separating it from server capacity

If quota is enabled, inspect the mailbox's configured usage and limit:

doveadm quota get -u user@example.com

A user can hit a Dovecot or hosting-account quota while the server filesystem has plenty of free space. The opposite can also happen: the mailbox is below quota, but the filesystem itself is full.

Diagnostic order: userdb lookup, UID/GID, mailbox path, parent-directory access, filesystem writeability, free blocks, free inodes, then the applicable mailbox or account quota. Change only the layer that failed.

Why can mail be delivered successfully but not appear in the Inbox?

A successful dovecot_virtual_delivery transaction can place a message somewhere other than INBOX. If Exim records a successful local delivery, the transport is no longer the first suspect.

Dovecot LDA and LMTP can execute delivery-time filtering through Sieve when it is configured. A rule can use fileinto to place mail in Junk, Spam, Archive or a custom folder. Hosting control panels can also expose server-side filters that affect the same delivery path.

List the user's mailboxes:

doveadm mailbox list -u user@example.com

Then inspect the relevant Sieve or server-side filters for actions that file, redirect, discard or stop processing a message. If spam filtering is integrated into the mail stack, check the spam folder rather than assuming the message was rejected.

A common support pattern is simple: the server log says 250 ... Saved, while the user checks only INBOX. At that point repeatedly testing LMTP is wasted effort. Find where the message was filed.

Aliases and forwarders create another branch. An address can forward mail elsewhere, keep a local copy, or skip local delivery according to the routing configuration. If the final destination is unclear, test the address again:

exim -bt user@example.com

The IMAP client can add another layer of confusion. The message may exist on the server while the client has not subscribed to the folder, has stale synchronization state, or is connected to another mailbox. Checking the same account through webmail can help separate server-side delivery from client presentation. If the actual problem is that the user cannot authenticate to the mailbox at all, move to the separate mail server authentication setup checks; local delivery and login are different failure paths.

Useful split: if Exim and Dovecot confirm a successful save, investigate the destination folder, filters and client. If delivery is deferred or rejected, go back to the transport and Dovecot error instead.

What should you avoid changing on a cPanel or panel-managed mail server?

On a panel-managed server, do not replace dovecot_virtual_delivery with configuration copied from a generic Exim tutorial until you know how the panel builds the active mail configuration.

Control panels can generate Exim and Dovecot configuration from templates, options and supported override mechanisms. Editing a generated working file may appear successful until the next configuration rebuild, package update or panel operation writes the generated configuration again.

Capture the effective configuration before changing it

exim -bP transport dovecot_virtual_delivery
exim -bt user@example.com
doveconf -n

Save the relevant output. If LMTP is involved, record the endpoint and permissions. If LDA is involved, record the actual binary path, command arguments and execution identity.

Make the change through the supported configuration path

On cPanel/WHM, use Exim Configuration Manager and the supported cPanel mechanisms that apply to the setting being changed rather than editing generated configuration behind the panel's back. Other hosting panels have their own source templates and override systems.

A configuration snippet from a normal Debian or AlmaLinux Exim installation can be technically valid and still be the wrong way to modify a cPanel-managed server.

Compare the effective configuration again after a rebuild

After the supported change, or after any configuration rebuild that might affect mail services, inspect the same transport again:

exim -bP transport dovecot_virtual_delivery

Compare it with the output recorded before the change. Then retest routing:

exim -bt user@example.com

Finally, send a real test message and follow its message ID through the log. A configuration that parses correctly but routes the recipient through the wrong path is still broken.

Avoid three shortcuts:

  • Do not replace LMTP with a dovecot-lda pipe simply because an old tutorial uses it.
  • Do not change mailbox UID/GID or apply recursive permissions before confirming the values returned by Dovecot userdb.
  • Do not treat a successful service restart as proof that mail delivery is fixed.

A panel rebuild that silently removes a manual edit is not an intermittent Dovecot problem. It is a configuration-management problem. Check the effective configuration before debugging the mailbox again.

When is dovecot_virtual_delivery healthy, and when should you investigate further?

dovecot_virtual_delivery is healthy when Exim selects the expected route, Dovecot resolves the recipient, the delivery mechanism can reach the mailbox layer, the message is accepted for storage and Exim finishes processing it without a delivery defer.

For one test mailbox, verify the whole chain:

  • exim -bt user@example.com selects the expected router.
  • The expected dovecot_virtual_delivery transport is assigned.
  • The transport definition identifies LDA, LMTP or the actual configured mechanism.
  • doveadm user user@example.com resolves the intended mailbox.
  • Dovecot logs contain no matching userdb, LMTP, quota, permission or storage error.
  • The relevant filesystem has free blocks and inodes.
  • The mailbox or hosting-account quota is not exhausted.
  • UID, GID and mailbox ownership match the intended virtual-user design.
  • A real message receives a successful local delivery response.
  • The message reaches the expected mailbox folder.

Where should you stop troubleshooting and change layers?

Result What it means Next layer
exim -bt chooses the wrong route The recipient has not reached the intended Dovecot delivery path Exim routers, aliases, redirects, domain configuration
Exim route is correct, but doveadm user fails Exim and Dovecot disagree about the recipient Dovecot userdb and account mapping
User resolves, but LMTP is unavailable The mailbox exists, but the handoff fails Dovecot service, LMTP listener, socket and permissions
LMTP works, but Dovecot returns permission, quota or storage errors Delivery reached the mailbox layer UID/GID, path, quota, filesystem and mailbox backend
Dovecot returns a successful 250 ... Saved Local delivery succeeded Sieve, mailbox folder, alias behaviour or mail client

One mailbox failing points first toward recipient-specific routing, userdb, quota or storage. Every mailbox failing at once points first toward shared services, sockets, filesystems and backends. That distinction alone can save a long trip through the wrong layer.

If all checks pass, leave the transport alone.

If it routes, resolves, saves and completes, dovecot_virtual_delivery is doing its job.

Frequently asked questions
No. It is commonly the name of an Exim transport used for delivery to virtual mailboxes handled by Dovecot. The delivery result after the transport name determines whether the operation succeeded or failed.
Usually no. It is typically an Exim transport label. Inspect the Exim transport definition to see whether it invokes Dovecot LDA, uses LMTP, or follows another local delivery path.
Check the effective Exim transport. A pipe transport that invokes dovecot-lda indicates LDA, while an LMTP transport or connection to a Dovecot LMTP endpoint indicates LMTP delivery.
Exim and Dovecot may be using different account data or mappings. If exim -bt routes the address correctly but doveadm user cannot resolve it, investigate Dovecot userdb and mailbox provisioning before changing filesystem permissions.
Read the complete Exim error and match its timestamp with the Dovecot log. Then check the relevant layer: LMTP service or socket, userdb, quota, UID/GID, filesystem space, inodes or mailbox storage.
They can remain in the Exim queue and be retried according to the active retry configuration. After fixing the cause, check exim -bp and inspect or retry the affected message instead of deleting it automatically.
Successful local delivery does not guarantee INBOX placement. Sieve rules, spam filtering, aliases, forwarding or the mail client can place or display the message elsewhere.
Avoid editing generated Exim configuration directly. Inspect the effective transport first, make changes through the supported cPanel configuration mechanism, then compare the effective transport and test a real delivery again.
Related articles
Understanding dovecot_virtual_delivery in Dovecot
Understanding dovecot_virtual_delivery in Dovecot Mail Server
"Retry Timeout Exceeded" in cPanel: What It Means and How to Fix It