Skip to content

ExchangeOnlineManagement and Microsoft.Graph PowerShell modules are mutually incompatible in the same session due to MSAL/WAM conflicts #3576

Open

Description

@c3maw

Describe the bug

When both ExchangeOnlineManagement and Microsoft Graph PowerShell SDK are loaded in the same PowerShell session, interactive authentication fails consistently. Whichever module loads second fails with MSAL RuntimeBroker NullReferenceException or MissingMethodException. Each module works independently.

Environment

PowerShell: Windows PowerShell 5.1 and PowerShell 7.x (both affected)
ExchangeOnlineManagement: 3.8.x – 3.9.2
Microsoft.Graph PowerShell: 2.26+ (also confirmed with 2.34+)
OS: Windows 10 / 11
Auth: Interactive (WAM enabled by default)

Expected behavior

Both modules should be able to authenticate in the same process, or at minimum fail with a documented, deterministic error.

How to reproduce

Import-Module ExchangeOnlineManagement
Import-Module Microsoft.Graph

Connect-ExchangeOnline   # FAILS if 2nd
# or
Connect-MgGraph          # FAILS if 2nd

Reversing the import order reverses which module fails.

SDK Version

2.36.1

Latest version known to work for scenario above?

<2.26 (I think)

Known Workarounds

The only workaround I've found is to execute commands for one of these modules in a separate Powershell session

Debug output

Click to expand log ```

Import-Module Microsoft.Graph -Debug
VERBOSE: Loading module from path 'C:\Program
Files\WindowsPowerShell\Modules\Microsoft.Graph\2.36.1\Microsoft.Graph.psd1'.

Confirm
Continue with this operation?
[Y] Yes [A] Yes to All [H] Halt Command [S] Suspend [?] Help (default is "Y"): A
VERBOSE: Cannot verify the Microsoft .NET Framework version 4.7.2 because it is not included in the list of permitted
versions.
Import-Module : Function Get-MgGroupThread cannot be created because function capacity 4096 has been exceeded for this
scope.
At line:1 char:2

  • Import-Module Microsoft.Graph -Debug
  •  + CategoryInfo          : InvalidOperation: (Get-MgGroupThread:String) [Import-Module], SessionStateOverflowExcept
    ion
     + FullyQualifiedErrorId : FunctionOverflow,Microsoft.PowerShell.Commands.ImportModuleCommand
    
    

dotnet --info

global.json file:
Not found

Host:
Version: 6.0.36
Architecture: x64
Commit: f1dd57165b

.NET SDKs installed:
No SDKs were found.

.NET runtimes installed:
Microsoft.NETCore.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 6.0.36 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

Download .NET:
https://aka.ms/dotnet-download

Learn about .NET Runtimes and SDKs:
https://aka.ms/dotnet/runtimes-sdk-info

Import-Module ExchangeOnlineManagement -Debug
VERBOSE: Loading module from path 'C:\Program
Files\WindowsPowerShell\Modules\ExchangeOnlineManagement\3.9.2\ExchangeOnlineManagement.psd1'.

Confirm
Continue with this operation?
[Y] Yes [A] Yes to All [H] Halt Command [S] Suspend [?] Help (default is "Y"): A
VERBOSE: Populating RepositorySourceLocation property for module ExchangeOnlineManagement.
VERBOSE: Loading module from path 'C:\Program
Files\WindowsPowerShell\Modules\ExchangeOnlineManagement\3.9.2.\netFramework\ExchangeOnlineManagement.psm1'.
VERBOSE: Exporting function 'Get-ModuleVersion'.
VERBOSE: Exporting function 'Test-Uri'.
VERBOSE: Exporting function 'Get-OrgNameFromUPN'.
VERBOSE: Exporting function 'Write-Message'.
VERBOSE: Exporting function 'Connect-ExchangeOnline'.
VERBOSE: Exporting function 'Connect-IPPSSession'.
VERBOSE: Exporting function 'Disconnect-ExchangeOnline'.
VERBOSE: Exporting cmdlet 'Get-EXOCasMailbox'.
VERBOSE: Exporting cmdlet 'Get-EXOMailbox'.
VERBOSE: Exporting cmdlet 'Get-EXOMailboxFolderPermission'.
VERBOSE: Exporting cmdlet 'Get-EXOMailboxFolderStatistics'.
VERBOSE: Exporting cmdlet 'Get-EXOMailboxPermission'.
VERBOSE: Exporting cmdlet 'Get-EXOMailboxStatistics'.
VERBOSE: Exporting cmdlet 'Get-EXOMobileDeviceStatistics'.
VERBOSE: Exporting cmdlet 'Get-EXORecipient'.
VERBOSE: Exporting cmdlet 'Get-EXORecipientPermission'.
VERBOSE: Exporting cmdlet 'Set-ExoAppSettings'.
VERBOSE: Exporting cmdlet 'Set-EXOCasMailbox'.
VERBOSE: Exporting cmdlet 'Set-EXOMailbox'.
VERBOSE: Exporting cmdlet 'Add-VivaModuleFeaturePolicy'.
VERBOSE: Exporting cmdlet 'Get-VivaModuleFeature'.
VERBOSE: Exporting cmdlet 'Get-VivaModuleFeatureEnablement'.
VERBOSE: Exporting cmdlet 'Get-VivaModuleFeaturePolicy'.
VERBOSE: Exporting cmdlet 'Remove-VivaModuleFeaturePolicy'.
VERBOSE: Exporting cmdlet 'Update-VivaModuleFeaturePolicy'.
VERBOSE: Exporting cmdlet 'Add-WorkforceInsightsDelegationAccess'.
VERBOSE: Exporting cmdlet 'Get-WorkforceInsightsDelegationAccess'.
VERBOSE: Exporting cmdlet 'Remove-WorkforceInsightsDelegationAccess'.
VERBOSE: Exporting cmdlet 'Get-VivaInsightsSettings'.
VERBOSE: Exporting cmdlet 'Set-VivaInsightsSettings'.
VERBOSE: Exporting cmdlet 'Set-MyAnalyticsFeatureConfig'.
VERBOSE: Exporting cmdlet 'Set-DefaultTenantMyAnalyticsFeatureConfig'.
VERBOSE: Exporting cmdlet 'Get-MyAnalyticsFeatureConfig'.
VERBOSE: Exporting cmdlet 'Get-DefaultTenantMyAnalyticsFeatureConfig'.
VERBOSE: Exporting cmdlet 'Add-VivaOrgInsightsDelegatedRole'.
VERBOSE: Exporting cmdlet 'Get-VivaOrgInsightsDelegatedRole'.
VERBOSE: Exporting cmdlet 'Remove-VivaOrgInsightsDelegatedRole'.
VERBOSE: Exporting cmdlet 'Get-CustomNudge'.
VERBOSE: Exporting cmdlet 'New-CustomNudge'.
VERBOSE: Exporting cmdlet 'Remove-CustomNudge'.
VERBOSE: Exporting cmdlet 'Set-CustomNudge'.
VERBOSE: Exporting cmdlet 'Get-CustomNudgeSettings'.
VERBOSE: Exporting cmdlet 'Set-CustomNudgeSettings'.
VERBOSE: Exporting cmdlet 'Get-CustomNudgeAssignment'.
VERBOSE: Exporting cmdlet 'Remove-CustomNudgeAssignment'.
VERBOSE: Exporting cmdlet 'New-CustomNudgeAssignment'.
VERBOSE: Exporting cmdlet 'Set-CustomNudgeAssignment'.
VERBOSE: Exporting cmdlet 'Get-DefaultTenantBriefingConfig'.
VERBOSE: Exporting cmdlet 'Get-UserBriefingConfig'.
VERBOSE: Exporting cmdlet 'Set-DefaultTenantBriefingConfig'.
VERBOSE: Exporting cmdlet 'Set-UserBriefingConfig'.
VERBOSE: Exporting cmdlet 'Add-EXOClientTelemetryWrapper'.
VERBOSE: Exporting cmdlet 'New-CmdletLogger'.
VERBOSE: Exporting cmdlet 'New-EXOClientTelemetryFilepath'.
VERBOSE: Exporting cmdlet 'Push-EXOTelemetryRecord'.
VERBOSE: Exporting cmdlet 'Clear-ActiveToken'.
VERBOSE: Exporting cmdlet 'Get-ConnectionContext'.
VERBOSE: Exporting cmdlet 'Get-ConnectionInformation'.
VERBOSE: Exporting cmdlet 'Get-EXOBanner'.
VERBOSE: Exporting cmdlet 'Get-HelpFiles'.
VERBOSE: Exporting cmdlet 'New-EXOModule'.
VERBOSE: Exporting cmdlet 'New-ExoPSSession'.
VERBOSE: Exporting cmdlet 'Test-ActiveToken'.
VERBOSE: Importing cmdlet 'Add-VivaModuleFeaturePolicy'.
VERBOSE: Importing cmdlet 'Add-VivaOrgInsightsDelegatedRole'.
VERBOSE: Importing cmdlet 'Get-ConnectionInformation'.
VERBOSE: Importing cmdlet 'Get-DefaultTenantBriefingConfig'.
VERBOSE: Importing cmdlet 'Get-DefaultTenantMyAnalyticsFeatureConfig'.
VERBOSE: Importing cmdlet 'Get-EXOCasMailbox'.
VERBOSE: Importing cmdlet 'Get-EXOMailbox'.
VERBOSE: Importing cmdlet 'Get-EXOMailboxFolderPermission'.
VERBOSE: Importing cmdlet 'Get-EXOMailboxFolderStatistics'.
VERBOSE: Importing cmdlet 'Get-EXOMailboxPermission'.
VERBOSE: Importing cmdlet 'Get-EXOMailboxStatistics'.
VERBOSE: Importing cmdlet 'Get-EXOMobileDeviceStatistics'.
VERBOSE: Importing cmdlet 'Get-EXORecipient'.
VERBOSE: Importing cmdlet 'Get-EXORecipientPermission'.
VERBOSE: Importing cmdlet 'Get-MyAnalyticsFeatureConfig'.
VERBOSE: Importing cmdlet 'Get-UserBriefingConfig'.
VERBOSE: Importing cmdlet 'Get-VivaInsightsSettings'.
VERBOSE: Importing cmdlet 'Get-VivaModuleFeature'.
VERBOSE: Importing cmdlet 'Get-VivaModuleFeatureEnablement'.
VERBOSE: Importing cmdlet 'Get-VivaModuleFeaturePolicy'.
VERBOSE: Importing cmdlet 'Get-VivaOrgInsightsDelegatedRole'.
VERBOSE: Importing cmdlet 'Remove-VivaModuleFeaturePolicy'.
VERBOSE: Importing cmdlet 'Remove-VivaOrgInsightsDelegatedRole'.
VERBOSE: Importing cmdlet 'Set-DefaultTenantBriefingConfig'.
VERBOSE: Importing cmdlet 'Set-DefaultTenantMyAnalyticsFeatureConfig'.
VERBOSE: Importing cmdlet 'Set-MyAnalyticsFeatureConfig'.
VERBOSE: Importing cmdlet 'Set-UserBriefingConfig'.
VERBOSE: Importing cmdlet 'Set-VivaInsightsSettings'.
VERBOSE: Importing cmdlet 'Update-VivaModuleFeaturePolicy'.
VERBOSE: Importing function 'Connect-ExchangeOnline'.
VERBOSE: Importing function 'Connect-IPPSSession'.
VERBOSE: Importing function 'Disconnect-ExchangeOnline'.

</details>


### Configuration

-OS: Windows 11
-Architecture: x64
-Not specific to this configuration. Tested on Windows Server 2019 x64 as well.
-$PSVersionTable:
Name                           Value
----                           -----
PSVersion                      5.1.26100.7920
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.26100.7920
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

### Other information

This appears to be a regression that was previously mitigated in ExO module 3.6.0.
Multiple community reports confirm load-order dependency and incompatibility.
See related issues: #3254, #3331

Activity

  1. ramsessanchez commented on Apr 13, 2026

    @ramsessanchez
    Contributor

    c3maw unfortunately this is a known issue due to the way that the Exo module team handles dependency loading and the way our modules do. We have reached out to the Exo team in an effort to align the two, however we do not have a set date for when this change will happen.

  2. c3maw commented on Apr 13, 2026

    @c3maw
    Author
  3. cdquinn commented on Apr 22, 2026

    @cdquinn

    I can verify that the issue does not happen with ExchangeOnlineManagement Module 3.9.2 and Microsoft.Graph.Authentication 2.32.0 when using Certificate authentication.
    However, The following produces a Error Without even doing a login
    Import-Module -Name ExchangeOnlineManagement
    Import-Module -Name Microsoft.Graph.Authentication -RequiredVersion 2.36.1

    Import-Module : Method 'GetTokenAsync' in type 'Microsoft.Graph.PowerShell.Authentication.Core.Utilities.UserProvidedTokenCredential' from assembly 'Microsoft.Graph.Authentication.Core, Version=2.36.1.0, Culture=neutral,
    PublicKeyToken=31bf3856ad364e35' does not have an implementation.
    At line:1 char:1

    • Import-Module -Name Microsoft.Graph.Authentication -RequiredVersion 2 ...
    •   + CategoryInfo          : NotSpecified: (:) [Import-Module], TypeLoadException
        + FullyQualifiedErrorId : System.TypeLoadException,Microsoft.PowerShell.Commands.ImportModuleCommand
      
  4. secretworkpersona commented on Apr 30, 2026

    @secretworkpersona

    We use certificate authentication. Importing Graph first allows both modules to coexist, but importing Exchange first results in a conflict with the Microsoft.Graph.Authentication module. To work around this I ensure Microsoft.Graph.Authentication is imported before Exchange.

    The script I use to connect to Exchange Online does two steps:

    Import-Module -Name Microsoft.Graph.Authentication
    Connect-ExchangeOnline <cert stuff>
    
  5. 12Knocksinna commented on May 4, 2026

    @12Knocksinna
    Contributor

    MVPs have been pressing the various product groups that generate PowerShell modules for Microsoft 365 to do better by working together to coordinate change. There's a bunch of problems that need to be resolved. See:

    https://office365itpros.com/2026/03/18/microsoft-graph-issues/

    https://office365itpros.com/2025/09/24/assembly-clash-microsoft-365-ps/

  6. ASDF-PS commented on May 27, 2026

    @ASDF-PS

    Please could one of your wonderful people have a look at resolving this so Microsoft core modules co-exist with each other.
    I have a GUI app that works with AD \ Azure \ Intune \ CRM \ EXO but I ran into this issue on a clean install.

    Some related posts.

    Image

    For now I am using older versions until this is fixed.

    Image
  7. 4 remaining items

  8. amaiman commented on Jul 9, 2026

    @amaiman

    It's been another 3 months. Can we please get a status update with a firm date for resolution? This can't just continue to be ignored because teams within Microsoft refuse to work together.

  9. Sekers commented on Jul 14, 2026

    @Sekers

    For PowerShell 5.1 Desktop, I can go as high as Microsoft Graph 2.35.1 (with the current latest ExchangeOnlineManagement Module Version: 3.10.0) without problems.

    As soon as I update to 2.36.0 or later, a conflict occurs even in PS 5.1:

    Import-Module ExchangeOnlineManagement
    Import-Module Microsoft.Graph.Authentication
    
    Import-Module : Method 'GetTokenAsync' in type
    'Microsoft.Graph.PowerShell.Authentication.Core.Utilities.UserProvidedTokenCredential' from assembly
    'Microsoft.Graph.Authentication.Core, Version=2.36.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' does not
    have an implementation.
    At line:1 char:1
    + Import-Module Microsoft.Graph.Authentication
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [Import-Module], TypeLoadException
        + FullyQualifiedErrorId : System.TypeLoadException,Microsoft.PowerShell.Commands.ImportModuleCommand
    
  10. 12Knocksinna commented on Jul 22, 2026

    @12Knocksinna
    Contributor

    To add to your woes, V7.9 of the Teams module supports WAM. Now if you load Teams, you can't load the Graph SDK or Exchange, and if you load Teams, you can't load the Graph SDK or Exchange...

    Image
  11. c3maw commented on Aug 24, 2026

    @c3maw
    Author

    Additional findings: MSAL assembly collision persists on PowerShell 7 and is not WAM-related

    Following up on my original report with a cleaner reproduction and new evidence.

    Summary

    The failure is not caused by the WAM broker and not limited to PowerShell 5.1.
    It is an Microsoft.Identity.Client assembly version collision that occurs during
    credential builder construction, before any authentication flow is selected.

    Both InteractiveBrowserCredential and DeviceCodeCredential fail identically,
    which rules out the auth flow as a variable.

    Environment

    Component Version
    PowerShell 7.6.5
    ExchangeOnlineManagement 3.10.1
    Microsoft.Graph 2.36.1
    OS Windows 11 (fill in build)
    Module install scope AllUsers (C:\Program Files\WindowsPowerShell\Modules)

    Correction to my original report

    My first report included a SessionStateOverflowException / function capacity error.
    That was a separate PowerShell 5.1 $MaximumFunctionCount issue caused by importing
    the Microsoft.Graph meta-module, and it obscured the actual defect. The reproduction
    below imports only Microsoft.Graph.Authentication so nothing is masked.

    Import-Module succeeds for both modules. The failure occurs at Connect-MgGraph.

    Reproduction

    Fresh PowerShell 7 session, non-elevated.

    Import-Module ExchangeOnlineManagement
    Import-Module Microsoft.Graph.Authentication
    
    [AppDomain]::CurrentDomain.GetAssemblies() |
      Where-Object FullName -like "*Identity.Client*" |
      Select-Object FullName
    
    Connect-ExchangeOnline -DelegatedOrganization <tenant>.onmicrosoft.com
    Connect-MgGraph -TenantId <tenant>.onmicrosoft.com

    Loaded MSAL assemblies after both imports

    Microsoft.Identity.Client,                 Version=4.83.1.0
    Microsoft.Identity.Client.Broker,          Version=4.83.1.0
    Microsoft.Identity.Client.NativeInterop,   Version=0.19.4.0
    Microsoft.Identity.Client.Extensions.Msal, Version=4.78.0.0
    

    Note the version skew between Microsoft.Identity.Client (4.83.1.0) and
    Microsoft.Identity.Client.Extensions.Msal (4.78.0.0).

    Result — interactive (WAM) path

    Connect-MgGraph: InteractiveBrowserCredential authentication failed:
    Method not found: '!0 Microsoft.Identity.Client.BaseAbstractApplicationBuilder`1
    .WithLogging(Microsoft.IdentityModel.Abstractions.IIdentityLogger, Boolean)'.
    

    Result — device code path (WAM bypassed)

    Same session, using -Device / -UseDeviceCode on both connects:

    Connect-MgGraph: DeviceCodeCredential authentication failed:
    Method not found: '!0 Microsoft.Identity.Client.BaseAbstractApplicationBuilder`1
    .WithLogging(Microsoft.IdentityModel.Abstractions.IIdentityLogger, Boolean)'.
    

    Identical exception, different credential type.

    Analysis

    WithLogging is invoked while constructing the application builder, which happens
    before the credential flow executes. Because both credential types fail at the same
    point with the same missing method, the broker and the auth flow can be excluded.

    ExchangeOnlineManagement is imported first and its copy of
    Microsoft.Identity.Client wins the load. Microsoft.Graph.Authentication then calls
    into an MSAL build it was not compiled against, and the expected overload of
    BaseAbstractApplicationBuilder<T>.WithLogging is absent.

    PowerShell 7 provides AssemblyLoadContext, but module assemblies are not isolated by
    default, so first-load-wins behaviour is the same as on .NET Framework.

    Why the existing workarounds do not apply

    Suggested workaround Result
    Use PowerShell 7 instead of 5.1 Still fails
    Use -UseDeviceCode to bypass WAM Still fails
    Import submodules instead of the meta-module Still fails (avoids a separate 5.1 issue only)

    The only reliable mitigation found is running each module in a separate process.

    Impact

    For CSP/MSP scenarios this is a significant limitation. Common administrative tasks
    require Exchange Online and Microsoft Graph in combination — for example correlating
    Unified Audit Log records with Entra sign-in logs during an account compromise
    investigation. Splitting these across processes and marshalling intermediate results
    adds meaningful complexity to otherwise straightforward scripts.

    Still to test

    • Reverse import order (Microsoft.Graph.Authentication first, then
      ExchangeOnlineManagement) to confirm the failure is symmetric
    • Whether an explicit AssemblyLoadContext per module is a viable workaround

    Suggested resolution

    Align the Microsoft.Identity.Client version between the two modules, or load module
    assemblies into isolated contexts so both can coexist in a single session.

  12. c3maw commented on Aug 26, 2026

    @c3maw
    Author

    Root Cause: Microsoft.Graph.Authentication Binds to a Resident Microsoft.Identity.Client Instead of Loading Its Own

    Follow-up with a controlled reproduction across all four combinations of connect order and authentication mode, capturing loaded MSAL assemblies at each stage.

    Transcripts for all four runs are attached.

    Summary

    Microsoft.Graph.Authentication (2.39.0) ships Microsoft.Identity.Client 4.82.1.0. ExchangeOnlineManagement (3.10.1) ships 4.83.1.0.

    Only one of four combinations works:

    Connect order Auth mode Result Failure
    Graph → EXO device code works —
    Graph → EXO interactive EXO fails NullReferenceException in RuntimeBroker..ctor
    EXO → Graph device code Graph fails MissingMethodException on WithLogging
    EXO → Graph interactive Graph fails MissingMethodException on WithLogging

    The two failures have different mechanisms and may warrant separate fixes.

    Corrections to My Earlier Reports

    1. My original report included a SessionStateOverflowException / function capacity error. That was an unrelated PowerShell 5.1 $MaximumFunctionCount issue caused by importing the Microsoft.Graph meta-module, and it masked the real defect. All reproductions below import only Microsoft.Graph.Authentication.

    2. I previously described this as depending on import order. That was wrong.Import-Module loads no MSAL assemblies for either module — every run below shows(none) after both imports. Connect order is the variable.

    Environment

    Component Version
    PowerShell 7.6.5 (Core)
    OS Windows 11, build 10.0.26100
    ExchangeOnlineManagement 3.10.1
    Microsoft.Graph.Authentication 2.39.0

    All four runs were non-elevated, in a fresh process, with both modules installed to a single module root — one version of each, verified in every transcript to rule out shadowing.

    Mechanism

    The Asymmetry

    When ExchangeOnlineManagement connects second, it loads its own Microsoft.Identity.Client 4.83.1.0 alongside the resident 4.82.1.0:

    === after Connect-MgGraph ===
        Microsoft.Identity.Client,                 Version=4.82.1.0
        Microsoft.Identity.Client.Extensions.Msal, Version=4.78.0.0
    
    === after Connect-ExchangeOnline ===
        Microsoft.Identity.Client,                 Version=4.82.1.0
        Microsoft.Identity.Client,                 Version=4.83.1.0    <-- loaded its own
        Microsoft.Identity.Client.Broker,          Version=4.83.1.0
        Microsoft.Identity.Client.Extensions.Msal, Version=4.78.0.0
    

    When Microsoft.Graph.Authentication connects second, it does not. It loads only its Extensions.Msal package and binds the core assembly to the resident 4.83.1.0:

    === after Connect-ExchangeOnline ===
        Microsoft.Identity.Client,                 Version=4.83.1.0
        Microsoft.Identity.Client.Broker,          Version=4.83.1.0
    
    === after Connect-MgGraph (failed) ===
        Microsoft.Identity.Client,                 Version=4.83.1.0
        Microsoft.Identity.Client.Broker,          Version=4.83.1.0
        Microsoft.Identity.Client.Extensions.Msal, Version=4.78.0.0    <-- only this loaded
    

    Microsoft.Identity.Client 4.82.1.0 is never loaded. The SDK then calls into 4.83.1.0, which does not expose the overload it was compiled against:

    Azure.Identity.AuthenticationFailedException
    DeviceCodeCredential authentication failed: Method not found: '!0
    Microsoft.Identity.Client.BaseAbstractApplicationBuilder`1
    .WithLogging(Microsoft.IdentityModel.Abstractions.IIdentityLogger, Boolean)'.
    
       at Azure.Identity.CredentialDiagnosticScope.FailWrapAndThrow(...)
       at Azure.Identity.DeviceCodeCredential.AuthenticateImplAsync(...)
       at Azure.Identity.DeviceCodeCredential.AuthenticateAsync(...)
       at Microsoft.Graph.PowerShell.Authentication.Core.Utilities.AuthenticationHelpers
            .GetDeviceCodeCredentialAsync(...)
       at Microsoft.Graph.PowerShell.Authentication.Core.Utilities.AuthenticationHelpers
            .GetTokenCredentialAsync(...)
       at Microsoft.Graph.PowerShell.Authentication.Core.Utilities.AuthenticationHelpers
            .SignInAsync(...)
       at Microsoft.Graph.PowerShell.Authentication.Cmdlets.ConnectMgGraph.ProcessRecordAsync()
    

    The interactive run produces the same exception via InteractiveBrowserCredential.AuthenticateImplAsync and AuthenticationHelpers.GetInteractiveBrowserCredentialAsync.

    Both paths converge on AuthenticationHelpers.GetTokenCredentialAsync, and both fail while Azure.Identity constructs the credential — before any authentication flow runs. That rules out the broker and the auth mode as causes of this particular failure.

    My Theory on Device Code

    Device code authentication does not load the broker stack at all. Interactive authentication loads Microsoft.Identity.Client.Broker and Microsoft.Identity.Client.NativeInterop.

    In the Graph-first / interactive run, both modules loaded broker components into separate contexts:

    === after Connect-ExchangeOnline (failed) ===
        Microsoft.Identity.Client,                 Version=4.82.1.0
        Microsoft.Identity.Client,                 Version=4.83.1.0
        Microsoft.Identity.Client.Broker,          Version=4.82.1.0
        Microsoft.Identity.Client.Broker,          Version=4.83.1.0
        Microsoft.Identity.Client.Extensions.Msal, Version=4.78.0.0
        Microsoft.Identity.Client.NativeInterop,   Version=0.19.4.0
        Microsoft.Identity.Client.NativeInterop,   Version=0.19.4.0
    

    Note NativeInterop 0.19.4.0 appearing twice. It's the same version loaded into two contexts. RuntimeBroker's constructor then throws:

    System.NullReferenceException: Object reference not set to an instance of an object.
       at Microsoft.Identity.Client.Platforms.Features.RuntimeBroker.RuntimeBroker..ctor(
            CoreUIParent uiParent, ApplicationConfiguration appConfig, ILoggerAdapter logger)
       at Microsoft.Identity.Client.Broker.BrokerExtension...AddRuntimeSupport...
       at Microsoft.Identity.Client.PlatformsCommon.Shared.AbstractPlatformProxy.CreateBroker(...)
       at Microsoft.Identity.Client.Internal.Requests.InteractiveRequest.FetchTokensFromBrokerAsync(...)
       ...
       at Microsoft.Exchange.Management.AdminApiProvider.Authentication.MSALTokenProvider.GetAccessTokenAsync(...)
    

    NativeInterop wraps a native runtime component. Two managed wrappers over one native runtime is a plausible source of the null reference, though I have not instrumented that directly.

    This explains why Graph-first+device code is the only working combination: it is the only one where neither module instantiates the broker.

    Two Distinct Issues

    1. Microsoft.Graph.Authentication does not isolate its MSAL load. ExchangeOnlineManagement loads its own core assembly regardless of what is resident; the Graph SDK binds to whatever it finds. Making the Graph SDK behave the same way would render connect order irrelevant for the MissingMethodException.

    2. Broker components cannot coexist across load contexts. Even with cores correctly isolated, the interactive path fails when two versions of Microsoft.Identity.Client.Broker and two copies of NativeInterop are present. This failure surfaces in ExchangeOnlineManagement's token provider and may belong in that repository — filing there with a cross-reference so it does not fall between components.

    Workaround

    Connect to Microsoft Graph before Exchange Online, using device code authentication on both.

    Problems with the Workaround

    This is a narrow window. Device code flow is commonly restricted or blocked by Conditional Access because of its use in phishing attacks. In tenants with such a policy there is no working configuration for using both modules in one session.

    Impact

    CSP and MSP scenarios routinely require both modules together. For example, correlating Unified Audit Log records with Entra sign-in logs during an account compromise investigation. The current failure messages give no indication that connect order or authentication mode is relevant, which makes this very difficult to diagnose from the error alone.

    Attached

    • msal-test-GraphFirst-Device.txt — the working combination
    • msal-test-GraphFirst-Interactive.txt — NullReferenceException
    • msal-test-ExoFirst-Device.txt — MissingMethodException
    • msal-test-ExoFirst-Interactive.txt — MissingMethodException

    Each transcript records the environment, available and loaded module versions, and the MSAL assemblies present at every stage.

    msal-test-ExoFirst-Device.txt
    msal-test-ExoFirst-Interactive.txt
    msal-test-GraphFirst-Device.txt
    msal-test-GraphFirst-Interactive.txt

  13. jonade commented on Sep 4, 2026

    @jonade

    We're an internal Microsoft team whose tooling connects to Exchange Online, Graph, Teams, SharePoint and Power Platform from a single Windows PowerShell 5.1 session, and we've been chasing this since December 2025 starting with EXO 3.7.0, across dozens of customer tenants. Three things that might be useful:

    Connect order matters on 5.1 too, not just on PS7. c3maw found that the trigger is the order you connect in rather than the order you import, and we see the same behaviour on Windows PowerShell 5.1. In one of our transcripts, running EXO 3.9.2, Connect-MgGraph goes through fine and then both Connect-IPPSSession and Connect-ExchangeOnline throw from inside Get-ConnectionContext:

    Method not found: 'Microsoft.Identity.Client.PublicClientApplicationBuilder
    Microsoft.Identity.Client.Broker.BrokerExtension.WithBroker(
    Microsoft.Identity.Client.PublicClientApplicationBuilder,
    Microsoft.Identity.Client.BrokerOptions)'
    

    We had already reordered our imports to load EXO ahead of the Graph SDK, and that made no difference, because the same failure returned two weeks later with the connect sequence unchanged, which suggests fairly strongly that import order is not where this is being decided.

    Some pairs do still break at Import-Module though, before anything connects. EXO 3.9.2 or 3.10.0 followed by Graph 2.38.0 gives Method 'GetTokenAsync' ... does not have an implementation, which is what Michael (@Sekers) hit with 2.36.0, so there appear to be two distinct failure modes on 5.1, one at import time and one at connect time, and they may be worth tracking separately from the PS7 repros.

    The contention also reaches further than the two modules in the title. This is what is installed on one of our engineer workstations, with EXO and Graph held below current by our own version pinning:

    Module Version Microsoft.Identity.Client
    Microsoft.PowerApps.Administration.PowerShell 2.0.217 4.66.2
    ExchangeOnlineManagement 3.9.2 4.74.1
    Microsoft.Online.SharePoint.PowerShell 16.0.27215.12000 4.74.1
    Microsoft.Graph.Authentication 2.35.1 4.78.0
    MicrosoftTeams 7.7.0 4.81.0

    That is five modules resolving against a single assembly identity across a 4.66 to 4.81 spread, and while we haven't reproduced failures involving Teams, SharePoint or Power Platform ourselves, anything that only reconciles EXO and Graph would leave the other three able to trip the same wire.

    We appreciate that a proper fix is hard, so the most useful thing in the meantime would be a statement of whether a supported in-process combination exists on Windows PowerShell 5.1 today and, if so, which versions in which order. A line in the troubleshooting guide would let everyone downstream pin to something known good rather than working the matrix out again after each release, and if the honest answer is that no such combination currently exists, that would be just as worth knowing.

  14. Csarly commented on Sep 15, 2026

    @Csarly

    exact same situation here! I stumbled into this today after updating my modules to the lastest version.
    3.10.1 ExchangeOnlineManagement
    2.39.0 Microsoft.Graph
    2.39.0 Microsoft.Graph.Beta
    Thanks to c3maw and Jonathan for the extensive analysis!
    Best, Alex

  15. Csarly commented on Sep 16, 2026

    @Csarly

    FYI, these versions work together for me on PoSh7.6.6 in one process:
    ExchangeOnlineManagement 3.9.2
    Microsoft.Graph 2.36.1
    Microsoft.Graph.Beta 2.36.1
    Best, Alex

  16. BlackV commented on Sep 18, 2026

    @BlackV

    Its 2026 man, how is this still a continuing issue

    ExchangeOnlineManagement 3.10.1
    Graph.Authentication     2.40.0
    
  17. ramsessanchez commented on Sep 23, 2026

    @ramsessanchez
    Contributor

    Thanks to Stephan van Rooij (@svrooij) we have an architectural revamp that allows for complete isolation. See #3789 and expect these changes to roll out in v2.41.0 in the next week or so.

  18. satyajit321 commented on Oct 2, 2026

    @satyajit321

    ExchangeOnlineManagement Version 3.10.1
    Connect-ExchangeOnline

    Microsoft.Graph.Authentication Version 2.41.0
    Connect-MgGraph

    Latest modules are out and it still fails, only workaround is loading Graph first and EXO later, however not always reliable as already called out for reasons earlier in this post.

  19. TheFiZi commented on Oct 2, 2026

    @TheFiZi

    I was running into the problem this issue describes today. Upgraded to:

    • PowerShell 7.6.6 (was using 7.6.5 before so not a big jump)
    • ExchangeOnlineManagement 3.10.1
    • Graph 2.41.0

    Everything appeared to work and fixed the error I was experiencing. I did connect to Graph first and EXO second.

    Only ran my script twice since the upgrade, takes over an hour to run so there was a good gap between runs.

  20. josedper commented on Oct 7, 2026

    @josedper

    At least one failure in this thread is System.Text.Json, not Microsoft.Identity.Client

    We have been chasing this on Windows PowerShell 5.1 and managed to reproduce one of these failures
    deterministically. The mechanism turned out not to be the MSAL skew the thread has mostly focused
    on, so it seemed worth writing up.

    The exception chain

    System.TypeInitializationException
      The type initializer for 'Azure.Identity.AuthenticationRecord' threw an exception.
        <- System.MissingMethodException
           Method not found: 'System.Text.Json.JsonEncodedText
             System.Text.Json.JsonEncodedText.Encode(System.String,
               System.Text.Encodings.Web.JavaScriptEncoder)'.
    

    Azure.Identity, shipped by Microsoft.Graph.Authentication, calls a System.Text.Json overload
    that is absent from the System.Text.Json left resident by ExchangeOnlineManagement when EXO
    loads first.

    Microsoft.Identity.Client is a bystander in this particular failure. In the failing run it
    resolves to EXO's copy and never throws. Aligning MSAL between the two modules would not fix
    it.

    Reproduction

    Clean Windows PowerShell 5.1 (5.1.26100), both modules installed into an isolated PSModulePath
    so nothing else could shadow them, five runs per combination, interactive Connect-MgGraph:

    Import order ExchangeOnlineManagement Microsoft.Graph.Authentication Result
    EXO first 3.10.0 2.33.0 fails 5 / 5
    Graph first 3.10.0 2.33.0 passes 5 / 5
    EXO first 3.10.0 2.35.1 passes 5 / 5
    EXO first 3.9.2 2.33.0 passes 5 / 5
    Graph first 3.9.2 2.33.0 passes 5 / 5

    25 runs, no inconclusive results.

    Two traps worth flagging for anyone trying to reproduce this:

    • A cached authentication record masks it. With ~/.mg/mg.authrecord.json present,
      Connect-MgGraph acquires silently and never initialises the failing type. This probably
      explains a good deal of the reported intermittency.

    • Device code does not exercise the failing path. Only the interactive flow initialises
      AuthenticationRecord:

      Auth mode EXO 3.10.0 then Auth 2.33.0
      Device code passes
      Interactive fails 5 / 5

      That matches c3maw's observation that Graph-first plus device code was the only working
      combination in their matrix, and it means device-code testing will not surface this class of
      regression.

    This thread looks like three defects, not one

    1. MissingMethodException on MSAL builder methods (WithBroker, WithLogging) — MSAL skew.
    2. TypeLoadException on GetTokenAsync at Import-Module — reported by Michael (@Sekers) and others, and
      tracked in Import-Module Microsoft.Graph.Authentication 2.34.0 Error GetTokenAsync #3479.
    3. TypeInitializationException on Azure.Identity.AuthenticationRecord — System.Text.Json
      skew, described above.

    A fix for any one of them would not necessarily address the others, so they may warrant separate
    tracking.

    Current versions have not closed it, and #3810 is the same family

    Re-measured this week on Windows PowerShell 5.1, three runs per combination, real interactive
    sign-ins:

    EXO / Graph.Authentication Import order Result
    3.10.1 / 2.40.0 Graph first ok
    3.10.1 / 2.40.0 EXO first Graph fails at Import-Module
    3.10.1 / 2.41.1 either order fails

    2.41.x is unusable for us on 5.1 for two independent reasons. It binds Microsoft.Identity.Client
    4.90.0 while EXO 3.10.1 binds 4.83.1, and it requires System.Text.Json 10, which only exists on
    PowerShell 7.6 and later — that is #3810.

    Worth noting that #3810 is the same class of problem as mechanism 3 above: a
    System.Text.Json version requirement the host cannot satisfy. One is a conflict with whatever EXO
    loaded first, the other a conflict with what the runtime provides at all. If the MSAL alignment
    work lands without also pinning down System.Text.Json, this family will keep reappearing.

    The practical mitigation, and independent confirmation

    On 5.1 today, importing the Graph SDK before Exchange Online is what works. We did not arrive
    at that alone — Satyajit321 (@satyajit321) and Eric (@TheFiZi) both reached it independently on 2 October, before we
    had posted anything here:

    the only workaround is loading Graph first and EXO later

    — Satyajit321 (@satyajit321), #3576 (comment)

    Everything appeared to work and fixed the error I was experiencing. I did connect to Graph first
    and EXO second.

    — Eric (@TheFiZi), #3576 (comment)

    Eric (@TheFiZi)'s result is on PowerShell 7.6.6 with 2.41.0, which is consistent with the table above
    rather than in tension with it: 7.6 is the first host that ships System.Text.Json 10, so 2.41.x
    has what it needs there. On 5.1 it does not.

    It is a workaround, not a fix. It depends on load order being under the caller's control, which is
    not true of every script, and it does not survive a version bump on either side without retesting.
    We have a worked example of applying it — import order, plus explicitly tested version ceilings
    rather than open-ended ones — in o365soa/soa#161, in
    case it is useful to anyone here.

    Offer

    Mechanism 3 reproduces without a tenant. The exception is thrown while the credential is being
    constructed, before any authentication begins: no credentials, no network. That makes it cheap to
    assert in CI — import the two modules in a given order, call Connect-MgGraph, and check that it
    reaches the auth prompt rather than throwing.

    Happy to contribute such a check, or the standalone repro harness, if the maintainers would find
    either useful.

    Related: #3479, #3810, #3394, #2978.

  21. svrooij commented on Oct 7, 2026

    @svrooij
    Contributor

    You can read the full story about the changes here https://svrooij.io/2026/10/06/microsoft-graph-dependency-issues/

    And the system.text.json issue already has a fix which they just need to release....

    #3813

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions