The sync error that doesn’t look like an error

A Microsoft Entra Connect Health alert landed last week. Eleven sync errors. It went to one mailbox, someone forwarded it on, and that is the only reason I saw it.

I expected eleven broken accounts. I found nine people who looked completely fine.

That gap is the whole story.

What “fine” was hiding

Here is the part worth sitting with.

When a mail contact holds an address, it is not a dead end. A contact exists to forward — that is its entire job. So mail sent to the address does not bounce and nobody gets an error. It is delivered, quietly, to wherever that contact points.

In our case, that was the company the person used to work for.

So for the months this sat there, a colleague could type a name in Outlook, get the right address, write something about a client, and send it out of the building. No warning, no non-delivery report, no trace in anyone’s mailbox except the recipient’s. The people affected were not missing a feature. They were reachable at an address that was not theirs any more.

Nothing about that shows up as an outage, which is exactly why it survived so long.

Why a broken account looks healthy

When Entra Connect hits a conflict, it does not reject the object. Duplicate attribute resiliency quarantines the conflicting attribute and provisions everything else.

So the account is created. The person signs in, has Teams, has a mailbox, appears in the address list. Every screen an admin would check is green. What they do not have is their own email address, because that one attribute was refused. Sometimes Entra invents a UPN to keep going, and someone ends up signing in as name15516@tenant.onmicrosoft.com without anyone noticing.

Five checks pass. The sixth is the one the account was created for.

The cause

We are thirteen companies consolidating into one tenant. When someone joins, their old company still runs its own mail, so a mail contact is created for their external address. Correct and normal. The problem was that their new address had also been added to that same contact as an alias.

proxyAddresses is unique across the entire directory, not just across users. Users, groups and contacts share one namespace. The contact was created first, so it holds the address. The person’s real account asks for it, Entra refuses, and carries on.

Nine people, one cause, repeated.

The rule I got wrong

My first detection rule flagged any non-user object holding one of our verified domains.

It returned 9,332 addresses. Nine were real.

The rule was wrong in a useful way. Every acquired company’s contacts legitimately carry an internal alias in concatenated form, SurnameFirstname@ourdomain.com, alongside the tenant routing address. That is deliberate provisioning, and it collides with nothing.

The right rule is narrower. It is about collision, not ownership:

A contact holding one of our addresses is only a problem when a user account claims the same address.

Same data. 9,332 findings became 15.

If a detection rule returns thousands of results in an estate of a few thousand people, the rule is the bug, not the data.

Two practical notes

Fix it where the object is mastered. These contacts sync from Active Directory, so the change goes in AD. Edit the cloud object and it is overwritten on the next cycle. onPremisesSyncEnabled tells you which side owns it.

Never delete an X500 address. They are legacy Exchange distinguished names and they exist so replies from cached Outlook profiles still route. Delete one and users get IMCEAEX bounces weeks later, from a change nobody connects to the failure. Remove only the specific SMTP address that collides.

Why we stopped handling alerts and built a check

Of the 15 collisions, seven had not produced an error yet.

Seven people were provisioned in a way that guaranteed a future Microsoft alert, about different names, on an unpredictable morning. Finding them by responding to alerts was impossible, because they had not alerted.

So we built a monitoring page instead. It collects every morning and reports what it measured. Where a query did not run it says so rather than showing a figure, because a zero and a blank mean very different things and conflating them is how a dashboard starts lying. Findings are ordered by which business service they affect, and history is kept, so we can see direction rather than a snapshot.

Next is routing the important findings out by email, so acting on them does not depend on somebody remembering to open a page. That is the piece still to build, and it is the piece that decides whether any of this gets used.

If you run a hybrid tenant

Query onPremisesProvisioningErrors across users, groups and contacts, on a schedule rather than when Microsoft writes to you.

Check whether any account is sitting on a system-generated UPN. It is a reliable sign something was quarantined at creation.

And decide who owns the Entra Connect Health alerts. Ours reached one mailbox and moved because someone chose to pass it on. That is not a monitoring strategy — that is luck, and luck is not something you can put in a handover document.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Website Powered by WordPress.com.

Up ↑