Repository navigation
Connect-MgGraph fails after Connect-ExchangeOnline #3394
Description
Describe the bug
I don't know, if this is related to the ExchangeOnlineManagement module (my suspicison) or to Microsoft.Graph, but you should know; too, I guess:
I updated Microsoft.Graph from 2.29.1. to 2.30.0 yesterday and ExchangeOnlineManagement from 3.8.0 to 3.9.0. After the update I found that when I run Connect-ExchangeOnline before Connect-MgGraph, the latter fails with the following error:
Connect-MgGraph: ClientCertificateCredential authentication failed: Method not found: '!0 Microsoft.Identity.Client.BaseAbstractApplicationBuilder`1.WithLogging(Microsoft.IdentityModel.Abstractions.IIdentityLogger, Boolean)'.
When I run Connect-MgGraph first and then Connect-ExchangeOnline, it works.
Expected behavior
IMO it should not matter, which command is run first.
How to reproduce
- On Powershell 7.5.2 ...
- Install Microsoft.Graph 2.30.0
- Install ExchangeOnlineManagement 3.9.0
- First run Connect-ExchangeOnline. ( I used certificate authentication )
- Second run Connect-MgGraph. It does not matter if user or certificate authentication. I tried both
- You should get the error described above
SDK Version
2.30.0
Latest version known to work for scenario above?
2.29.1 together with ExchangeOnlineManagement 3.8.0
Known Workarounds
- First run Connect-MgGraph
- Then run Connect-ExchangeOnline
Debug output
Click to expand log
```DEBUG: ClientCertificateCredential.GetToken invoked. Scopes: [ https://graph.microsoft.com/.default ] ParentRequestId:
DEBUG: ClientCertificateCredential.GetToken was unable to retrieve an access token. Scopes: [ https://graph.microsoft.com/.default ] ParentRequestId: Exception: Azure.Identity.AuthenticationFailedException (0x80131500): ClientCertificateCredential authentication failed: Method not found: '!0 Microsoft.Identity.Client.BaseAbstractApplicationBuilder1.WithLogging(Microsoft.IdentityModel.Abstractions.IIdentityLogger, Boolean)'. ---> System.MissingMethodException (0x80131513): Method not found: '!0 Microsoft.Identity.Client.BaseAbstractApplicationBuilder1.WithLogging(Microsoft.IdentityModel.Abstractions.IIdentityLogger, Boolean)'.
Connect-MgGraph: ClientCertificateCredential authentication failed: Method not found: '!0 Microsoft.Identity.Client.BaseAbstractApplicationBuilder`1.WithLogging(Microsoft.IdentityModel.Abstractions.IIdentityLogger, Boolean)'.
</details>
### Configuration
Name Value
PSVersion 7.5.2
PSEdition Core
GitCommitId 7.5.2
OS Microsoft Windows 10.0.26100
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Architecture: x64
### Other information
_No response_
Activity
FabienTschanz commentedon Sep 12, 2025
The issue is with the assembly context of the module. Microsoft does not implement the assembly loading context properly, leading to those assemblies being loaded globally instead of only in the application context it belongs to. This is something that occurs again and again and they don't fix it... Guess we have to wait until the next release fixes it (for another couple of months until the next one)...
robinmalik commentedon Sep 18, 2025
This has been an issue for years now as I remember having to inform colleagues to avoid doing this. Given that the Exchange team released a PowerShell snap-in just a few years ago despite modules being favoured since 2010, I'm not convinced they will be working collaboratively with more modern teams within Microsoft to help resolve this. I hope I'm wrong though.
KevinPinel commentedon Oct 8, 2025
This does work in PS5. It doesn't help when scripts also rely on PS7 only modules
gavinbarron commentedon Oct 20, 2025
We are working with the EXO team to resolve this issue and ensure it should not happen again.
In the meantime if you reverse the order in which the
Connect-*cmdlets are called the cmdlets work as expected based on out testingSkaldhor commentedon Nov 20, 2025
Gavin Barron (@gavinbarron) Is there any update regarding this issue?
It took more than a month to acknowledge the bug and now another month passed without a fix.
Since these are enterprise tools we need to manage our M365 services, I think there should be some kind of higher priority, rollback to working versions or some kind of communication at least.
I think there's no M365 admin center service incident, no message on the Exchange techcommunity Blog etc.
mognify commentedon Dec 8, 2025
lol, pretty insane that it's fixed by importing ExchangeOnlineManagement before importing any Microsoft.Graph.* modules
but it works... very satisfying fix tbh... simple, straight-forward, reproducible with minimal effort...
I wonder what goes on that causes it to have issues if the Graph modules are imported first
gavinbarron commentedon Dec 18, 2025
Florian Kolb (@Skaldhor) we're trying to work with the EXO team on a comprehensive fix.
I apologize that this is taking too long, but the reality here is that we have limited resources and the EXO team hasn't been willing to collaborate on a proper fix. So, while we could ship a fix that addresses this for the current versions without their collaboration, we'll wind up in the same broken state again when they ship again.
Skaldhor commentedon Dec 18, 2025
Gavin Barron (@gavinbarron)
I understand there are internal collaboration issues at Microsoft and appreciate you being open about it and trying to achieve a future proof solution.
However, from a customer/consumer point of view: This is a bug/issue in enterprise management tools we need and pay for (indirectly). I would expect this to be fixed "relatively" timely, especially since you already seem to know the issue, cause and (potential) fix.
Even without the EXO team you could publish a working version for now and work on a future proof solution with them in the background.
Steltek commentedon Feb 11, 2026
I now have the reverse issue:
Inverting the commands and connecting to ExchangeOnline before Graph works. (If I want to add MicrosoftTeams to the same session, I have to connect to it before ExchangeOnline because those two modules also constantly conflict with one another.)
PowerShell: 7.5.4
Microsoft.Graph: 2.35.1
ExchangeOnlineManagement: 3.9.2
MicrosoftTeams: 7.6.0
This is really painful! Please write your PowerShell modules such that they will function regardless of what order they are loaded/started in.
PimpJuiceIT commentedon Feb 12, 2026
Ridiculous, upon testing deprovisioning scripts post account termination, things not working even loading Exchange Online first. Now I have to spend time rewriting the logic in a way that works with the most up-to-date methods that work today to workaround the bugs (in all sections), and hope that it stays working or else redo it again on the next update for the next bug—I will remain hopeful it is not a continual issue that is reintroduced on the next release.
At least I run the module updates on a different VM machine for initial testing but would be nice for some consistency with updated modules. The order does seem to load to get a little further but run into other errors after that part of the logic is adjusted now. I modernized these scripts last round using a mix of Graph and Exchange Online commands. Now I need to figure out the order of logic for loading modules.
For now, I'll hold off on updating my main machine until something is released fixing the bugs that were introduced which I can validate work without slews of time needed rewriting scripts and testing logic. In my case, on-prem is the source of authority and syncs over to M365 Entra Connect but before terminating accounts, all on-prem and Azure/Entra/Exchange Online details need documented in a pre-term text file.
gaelcolas commentedon Feb 12, 2026
Working around this issue is a pain.
Gavin Barron (@gavinbarron) Let me add that not implementing ALC will never properly fix the issue: https://github.com/jborean93/PowerShell-ALC
Without that, it will always depend on the MSAL signatures and backward compatibility, and which one is loaded first...
I'm sure if you reach out to the PS team internally (i.e. Steve L), he'll happily point you in the right direction.
For those looking for a temporary workaround to make your life slightly less miserable, Sam Erde (@SamErde) has build this workaround here: https://github.com/maester365/maester/blob/main/powershell/internal/Get-ModuleImportOrder.ps1#L1
SteveL-MSFT commentedon Feb 12, 2026
See https://learn.microsoft.com/en-us/powershell/scripting/dev-cross-plat/resolving-dependency-conflicts?view=powershell-7.5
13 remaining items
Mike-Crowley commentedon Sep 21, 2026
Confirming this is still present on the current latest: PowerShell 7.6.6, Microsoft.Graph.Authentication 2.40.0, ExchangeOnlineManagement 3.10.1. EXO-then-Graph gives the WithLogging method-not-found; Graph-then-EXO gives the RuntimeBroker NullReferenceException.
One refinement to the version-conflict framing above (e.g. Fabien Tschanz (@FabienTschanz)'s 8.15-vs-8.14 note): I traced the assembly binding, and matching the MSAL versions does not help. Both modules now ship the same Microsoft.Identity.Client (4.83.1) and the same native msalruntime, and it still fails. The break is cross-context type identity, not a version delta:
The practical implication: even a release that perfectly aligned every MSAL version would still break as long as EXO populates Default and Graph falls back into it. More evidence for what gaelcolas (@gaelcolas) and Przemysław Kłys (@PrzemyslawKlys) already said, that EXO needs to load into its own ALC. Until then the isolation wrappers in this thread (DLLPickle, PSPublishModule's Import-IsolatedModule) are the only clean fixes; -DisableWAM sidesteps the Graph-first NullReferenceException but not the WithLogging clash.
SamErde commentedon Sep 21, 2026
Nice summary. Do you have an agent skill that checks to see if open issues are still relevant or have any potential new resolutions?
Mike-Crowley commentedon Sep 21, 2026
No, that was a one-off as a result of trying to work through the mechanics
Mike-Crowley commentedon Sep 25, 2026
On Sep 21 I said the clean fix was EXO loading into its own ALC. #3789 (merged Sep 23; no release contains it yet, v2.40.0 predates the merge) takes the other route: Graph isolates itself. It replaces msgraph-load-context, which had no Load override and fell back to Default, with a GraphAssemblyLoadContext that overrides Load and resolves MSAL, Azure.Identity and Microsoft.IdentityModel.Abstractions from Graph's own folder. Only Microsoft.Graph.Authentication.Core is bridged into Default, and the old AppDomain.AssemblyResolve handler is no longer registered on PS7. Graph can therefore no longer bind to EXO's MSAL in Default, so the WithLogging failure in this issue (EXO-then-Graph) should be gone by construction, and that no longer depends on which MSAL EXO ships (the concern in the Dec 18 comment).
Two caveats. The PR's test pre-loads a stub Microsoft.Identity.Client and connects with -AccessToken, so it verifies the load contexts, not WAM or the WithLogging path. And nothing in the PR exercises Graph-then-EXO (the RuntimeBroker NullReferenceException reported from Feb onward); that direction needs a test build. Windows PowerShell 5.1 keeps the AssemblyResolve approach and is not covered.
Maintainers: worth linking #3789 here alongside #3576, and keeping this open until a release confirms both directions.
svrooij commentedon Sep 25, 2026
Mike Crowley (@Mike-Crowley) eventually it is better if all modules that have dependencies upon Microsoft.Identity.Client (Msal) use a loader principle that looks the same.
robinmalik commentedon Sep 25, 2026
If only. The Exchange team run by their own rules with regard to PowerShell, from everything I've seen over the last 17+ years.
Mike-Crowley commentedon Sep 25, 2026
I built a small harness for this: one fresh pwsh per scenario, a load-state snapshot after every step. PowerShell 7.6.6, Microsoft.Graph.Authentication 2.40.0, ExchangeOnlineManagement 3.10.1, seven scenarios.
Observed, Graph-then-EXO:
EXO-then-Graph still fails (WithLogging MissingMethodException), so neither order works. Two same-session combinations connected: Graph, then Connect-ExchangeOnline -DisableWAM; or Graph via -AccessToken (token from Az.Accounts), then EXO as normal, because Graph never starts msalruntime.
Predictions, no build yet: #3789 fixes EXO-then-Graph by construction; Graph-then-EXO survives it, since EXO's bare-name P/Invokes still find Graph's started copy. Untested fixes: NativeInterop pins P/Invokes to its preloaded handle or tolerates a second startup; Graph uses a Graph-only file name; EXO gets its own load context or DllImportResolver. Related: #3576.
Ask: can the NativeInterop part be routed to the MSAL owners, or should I file it in MSAL.NET?
Harness and report: https://github.com/Mike-Crowley/graph-exo-loadorder
Mike-Crowley commentedon Oct 1, 2026
Microsoft's post today, Action Required: Upgrade ExchangeOnlineManagement PowerShell Module to Version 3.10.1 or Newer, puts an end date on the "stay on an old EXO" workaround: from 31 March 2027, interactive non-WAM sign-in on versions before 3.10.1 may fail. Their FAQ says WAM is not being required, so Graph first, then Connect-ExchangeOnline -DisableWAM (works today on 3.10.1) is not what they are retiring. The path they are hardening is the WAM one, and that is the path this issue breaks.
Mike-Crowley commentedon Oct 19, 2026
Re-ran the harness on the released 2.41.2 (PowerShell 7.6.7, ExchangeOnlineManagement 3.10.1, same nine scenarios, one fresh pwsh each). Every order now connects, including Graph-then-EXO.
Microsoft.Graph.Authenticationload context), so the WithLogging binding never happens.One caveat, reasoning rather than observation: EXO's bare-name binding still decides which runtime EXO runs on after a Graph sign-in. Today that copy is newer than EXO's own; the day EXO ships a newer NativeInterop than Graph, Graph-first puts EXO's interop on an older runtime again. The NativeInterop ask from my earlier comment (pin P/Invokes to the preloaded handle) still looks like the durable fix.
Full report: https://github.com/Mike-Crowley/graph-exo-loadorder/blob/main/report-2.41.2.md
🤖 Claude Mythos 5.1 (max effort) via Claude Code
svrooij commentedon Oct 21, 2026
The way the
AssemblyLoadContextis implemented does not provide a way to load multiple copies of Native binaries. The culprit, the msal broker, is designed to create a singleton that is reachable over a named pipe. And there can only be one running on the machine. If you were to load multiple on the same machine they will fight to respond to that named pipe.What if we fix this issue #3806 and then migrate all the other modules to call the new
Get-MgAccessToken -Scope ...command. Then all the external dependencies to the broker can be removed?Other solution is to always keep the versions equal, but that would require some advanced dependency management combined with synchronized release cycles
Mike-Crowley commentedon Oct 21, 2026
Thanks. Here is what the Oct 19 snapshots show on the two testable parts, with observed and inferred kept apart; one machine, one run per scenario, details in report-2.41.2.md.
On Get-MgAccessToken: Connect-ExchangeOnline has taken an external token since 3.1.0 (-AccessToken), so the route exists in principle. What I do not know is whether the Graph PowerShell client can be issued a token for the Exchange resource at all, and in any case it would cover scripts that opt in, while the default interactive path would still start EXO's own broker, which is where this issue lives. On keeping versions equal: 2.40.0 and EXO 3.10.1 already shared NativeInterop 0.19.4 and MSAL 4.83.1 and still collided, so equal versions are not sufficient on their own; the copy mapped first also has to accept a second startup. That is why a DllImportResolver that pins each module's P/Invokes to the copy it preloaded, in NativeInterop or in EXO, still looks to me like the change that does not depend on anyone's release calendar. If two started copies truly cannot coexist, that moves the fix to MSAL, and the two-live-copies observation above is the one data point I have against it.
🤖 Claude Mythos 5.1 (max effort) via Claude Code
svrooij commentedon Oct 21, 2026
Mike Crowley (@Mike-Crowley) the claude stuff does not really help. I have no clue what the issue is. Maybe I'm just a bit tired at the moment but from what I'm reading PowerShell assembly resolving does not handle native assemblies the same way as managed assemblies. That begs the question, why is this even built in native code 😉 (different team maybe)
Mike-Crowley commentedon Oct 21, 2026
Hey Stephan, sorry about that. I was using Claude to be comprehensive, since I'm sure Microsoft will be using AI as well to read and ingest this work. Here is my understanding, and what I'm proposing:
Your ALC fixed the .NET side. EXO-first works now on 2.41.2. What's left is msalruntime.dll, which is a native DLL, so the ALC doesn't cover it. Graph and EXO each ship their own copy, but Windows finds native DLLs by name. So whoever signs in first, the other module ends up using that first copy. On 2.40 that crashed. On 2.41.2 it still happens, but Graph's newer copy doesn't mind being started twice, so it works. That's luck, not a fix. If EXO ever ships a newer msalruntime than Graph, it could break again.
My proposal: each module should point its msalruntime calls at its own copy. Your ALC already does that for Graph (LoadUnmanagedDll). EXO doesn't. If EXO did the same, or if MSAL's NativeInterop package did it for everyone, load order wouldn't matter anymore. Get-MgAccessToken is still a good idea, but it only helps people who pass a token to EXO. Normal EXO sign-in would still start its own msalruntime.
svrooij commentedon Oct 21, 2026
I want the EXO team to remove the broker completely and make
Microsoft.Graph.Authenticationthe only module that ships the msalclient.Then the exo team can make a dependency upon this module and just call into the Get-MgAccessToken command under the covers
Maybe that last command can even be removed, and every call to exchange would just try to get a token (which will auto cache and refresh if needed)
Mike-Crowley commentedon Oct 21, 2026
I'd like to live in that utopia! But that means SharePoint, Teams, Azure, etc would all need to change their approach, and this multi-decade-old Microsoft org chart meme gives us an idea how that might go: https://assets.sbnation.com/assets/2907963/microsoftguns.jpg