LDAP aliases for migrated/local principals are synced but not used for local delivery

Issue Description

I’m seeing what appears to be inconsistent behaviour when migrating from the internal directory to an LDAP directory (LLDAP).

Environment
Latest Stalwart
LLDAP as the external directory
Existing installation originally used the internal directory
LDAP authentication configured and working correctly
LDAP configuration

The mailbox filter is:

(|(&(objectClass=person)(mail=?))(&(objectClass=person)(mailalias=?))(&(objectClass=groupOfNames)(mail=?)))

The email attributes are:

E-mail Attribute: mail
E-mail Alias Attribute: mailalias

LLDAP exposes the aliases correctly. For example:

dn: uid=chris,ou=people,dc=rowland,dc=au

mail: [email protected]
mailalias: [email protected]
mailalias: [email protected]

and an LDAP search on mailalias=* returns these values.

What works
LDAP authentication works.
IMAP authentication works.
JMAP authentication works.
Existing mailbox for chris is preserved.
Pocket ID integration works.
A brand new LDAP user with aliases works perfectly.

Example:

mail: [email protected]
mailalias: [email protected]

Sending to [email protected] results in:

queueName = “local”
accountId = 27

and the message is delivered successfully.

What does NOT work

chris is an existing account that originally existed in the internal directory and is now linked to LDAP.

After synchronisation:

the new LDAP aliases appear correctly in the Stalwart UI
the account authenticates via LDAP
the existing mailbox is retained

However, sending mail to a newly-added LDAP alias does not resolve locally.

Example:

mail: [email protected]
mailalias: [email protected]

Sending to:

[email protected]

results in:

queueName = “remote”

and the message is routed via my split-domain remote transport instead of being treated as a local address.

By comparison, an older alias that existed before migration:

[email protected]

results in:

queueName = “local”
accountId = 2

and delivers correctly.

Expected Behavior

Email to an alias imported from LDAP should work, even if the principal existed in Stalwart beforehand.

Actual Behavior

Aliases imported from LDAP to an existing principal are not recognised as local recipients, and disappear.

Stalwart Version

v0.16.x

Installation Method

Docker

Database Backend

RocksDB

Blob Storage

RocksDB

Search Engine

Internal

Directory Backend

LDAP

Additional Context

Summary

It appears that:

LDAP aliases for new LDAP-created principals participate in local address resolution correctly.
LDAP aliases for an existing local principal that has been migrated/linked to LDAP are displayed and synced, but are not used for local address resolution, even though authentication works and the mailbox is associated with the account.

Is this expected behaviour, or is there a way to rebuild or refresh the local address mapping for an existing principal after migrating to an external LDAP directory?

Happy to provide additional logs or test further if helpful.

I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.

on

I have searched this support forum (open and closed topics) and confirm this is not a duplicate.

on

I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.

on

The remote queue means that for that particular alias the LDAP recipient lookup came back as “not a local recipient,” so the message went to the outbound path. Stalwart re-queries LDAP on every RCPT for the alias, so the question is why an equality search for that address doesn’t return the migrated user, given that a new user’s alias and an older alias both resolve fine.

Could you grab three things? First, an auth trace for a delivery to the failing alias showing the LDAP query filter and its result. Second, the output of an actual equality search against LLDAP for that alias value ([email protected], not mailalias=*), since a presence match succeeding doesn’t prove the equality match returns the entry; a missing equality index or a case/whitespace difference on the migrated entry would explain it exactly. Third, confirm which directory is set for that domain and that no routing rule sends it to the remote transport before recipient resolution. That will tell us whether this is the LLDAP entry or the lookup path.