Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Dec 10, 2025

Changes proposed in this request

The retry logic in HttpManager.SendRequestAsync accessed headers[OAuth2Header.CorrelationId] before checking key existence, throwing KeyNotFoundException when headers were present but lacked the correlation ID (e.g., during Managed Identity token requests).

// Before: KeyNotFoundException when key missing
var correlationId = headers[OAuth2Header.CorrelationId];
string correlationIdMsg = headers.ContainsKey(OAuth2Header.CorrelationId) ? 
    $" CorrelationId: {correlationId}" : string.Empty;

// After: Check existence first
string correlationId = null;
string correlationIdMsg = string.Empty;

if (headers.ContainsKey(OAuth2Header.CorrelationId))
{
    correlationId = headers[OAuth2Header.CorrelationId];
    correlationIdMsg = $" CorrelationId: {correlationId}";
}

Core changes:

  • HttpManager.cs: Check ContainsKey before dictionary access
  • HttpManagerTests.cs: Add regression test TestRetryOnTimeoutWithHeadersButNoCorrelationIdAsync validating timeout with headers but no correlation ID

Testing

Added regression test that simulates retry timeout with headers that don't contain correlation ID. All existing HttpManagerTests (20 tests) pass.

Performance impact

None. Adds one dictionary lookup check per timeout exception path.

Documentation

  • All relevant documentation is updated.
Original prompt

This section details on the original issue you should resolve

<issue_title>[Bug] KeyNotFoundException during retry for getting Managed Identity token</issue_title>
<issue_description>### Library version used

4.78.0

.NET version

.NET 9.0 SDK
.NET 8.0 Target Framework

Scenario

ManagedIdentityClient - managed identity

Is this a new or an existing app?

The app is in production, I haven't upgraded MSAL, but started seeing this issue

Issue description and reproduction steps

We are seeing in our logging: KeyNotFoundExceptions with the retry mechanisme for aquiring token from the Managed Identity endpoint.

The error messages/stack traces:

False MSAL 4.76.0.0 MSAL.NetCore .NET 8.0.21 Linux [2025-12-09 07:00:33Z - eba86310-d513-4244-b369-c2b97226fa48] [Managed Identity] Exception: The given key 'client-request-id' was not present in the dictionary.
False MSAL 4.76.0.0 MSAL.NetCore .NET 8.0.21 Linux [2025-12-09 07:00:33Z - eba86310-d513-4244-b369-c2b97226fa48] Exception type: Microsoft.Identity.Client.MsalServiceException
, ErrorCode: managed_identity_request_failed
HTTP StatusCode 0
CorrelationId eba86310-d513-4244-b369-c2b97226fa48
---> Inner Exception Details
Exception type: System.Collections.Generic.KeyNotFoundException
To see full exception details, enable PII Logging. See https://aka.ms/msal-net-logging
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at Microsoft.Identity.Client.Http.HttpManager.SendRequestAsync(Uri endpoint, IDictionary`2 headers, HttpContent body, HttpMethod method, ILoggerAdapter logger, Boolean doNotThrow, X509Certificate2 bindingCertificate, Func`5 validateServerCert, CancellationToken cancellationToken, IRetryPolicy retryPolicy, Int32 retryCount)
at Microsoft.Identity.Client.ManagedIdentity.AbstractManagedIdentity.AuthenticateAsync(AcquireTokenForManagedIdentityParameters parameters, CancellationToken cancellationToken)

=== End of inner exception stack trace ===
To see full exception details, enable PII Logging. See https://aka.ms/msal-net-logging
at Microsoft.Identity.Client.ManagedIdentity.AbstractManagedIdentity.CreateAndThrowException(String errorCode, String errorMessage, Exception innerException, ManagedIdentitySource source)
at Microsoft.Identity.Client.ManagedIdentity.AbstractManagedIdentity.HandleException(Exception ex, ManagedIdentitySource managedIdentitySource, String additionalInfo)
at Microsoft.Identity.Client.ManagedIdentity.AbstractManagedIdentity.AuthenticateAsync(AcquireTokenForManagedIdentityParameters parameters, CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.ManagedIdentityAuthRequest.SendTokenRequestForManagedIdentityAsync(ILoggerAdapter logger, CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.ManagedIdentityAuthRequest.GetAccessTokenAsync(CancellationToken cancellationToken, ILoggerAdapter logger)
at Microsoft.Identity.Client.Internal.Requests.ManagedIdentityAuthRequest.ExecuteAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.<>c__DisplayClass11_1.<<RunAsync>b__1>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.Identity.Client.Utils.StopwatchService.MeasureCodeBlockAsync(Func`1 codeBlock)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)

Relevant code snippets

Could this line of code the cause of KeyNotFoundException and fail the retry mechanisme?

                    var correlationId = headers[OAuth2Header.CorrelationId];
                    string correlationIdMsg = headers.ContainsKey(OAuth2Header.CorrelationId) ?
                                                $" CorrelationId: {correlationId}" :
                                                string.Empty;

...

https://github.com/AzureAD/microsoft-authentication-library-for-dotnet/blob/964a07449f9d5183828fbd0e1e9d4d3e9b6d80c7/src/client/Microsoft.Identity.Client/Http/HttpManager.cs#L143C20-L143C77

Expected behavior

No response

Identity provider

Other

Regression

No response

Solution and workarounds

-</issue_description>

<agent_instructions>The problem is in HttpManager, when trying to read headers[OAuth2Header.CorrelationId]

Make sure to add a regression test for this.</agent_instructions>

Comments on the Issue (you are @copilot in this section)

@bgavrilMS Yes, thanks for raising. Looks like a recent change https://github.com//pull/5364 where we were trying to include correlation id.

We will get it fixed, but please note that error would still occur.</comment_new>


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: bgavrilMS <12273384+bgavrilMS@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix KeyNotFoundException during retry for Managed Identity token Fix KeyNotFoundException during retry when headers lack correlation ID Dec 10, 2025
Copilot AI requested a review from bgavrilMS December 10, 2025 12:35
@bgavrilMS bgavrilMS marked this pull request as ready for review December 11, 2025 16:09
@bgavrilMS bgavrilMS requested a review from a team as a code owner December 11, 2025 16:09
string correlationIdMsg = string.Empty;
string correlationId = null;

if (headers.ContainsKey(OAuth2Header.CorrelationId))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two lookups. But, in an exception‑path it’s not a big perf concern. Ideally the code could be,

if (headers.TryGetValue(OAuth2Header.CorrelationId, out var correlationId))
{
    correlationIdMsg = $" CorrelationId: {correlationId}";
    ex.CorrelationId = correlationId;
}

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] KeyNotFoundException during retry for getting Managed Identity token

3 participants