Library version used
4.66.1
.NET version
.Net6.0
Scenario
ConfidentialClient - service to service (AcquireTokenForClient)
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 have enabled ESTS-r globally. And we are seeing the following errors across the board. Can you help to take a look?
2025-04-23T12:45:47 [msg:1bd9][deq:998c] MsalUiRequiredException ERROR: RegionalClientCertificateCredential acquire token for tenant "" with parent requst ID "" failed. Exception: 'Microsoft.Identity.Client.MsalUiRequiredException' occured: AADSTS5000224: We are sorry, this resource is not available. If you are seeing this message by mistake, please contact Microsoft support. Trace ID: 22c5042e-23b3-4157-a5d5-14e787cec700 Correlation ID: 3aefdc8a-a61a-42d6-9da2-d5df9639826f Timestamp: 2025-04-23 12:45:47Z.
Stack: at Microsoft.Identity.Client.OAuth2.OAuth2Client.ThrowServerException(HttpResponse response, RequestContext requestContext)
at Microsoft.Identity.Client.OAuth2.OAuth2Client.CreateResponse[T](HttpResponse response, RequestContext requestContext)
at Microsoft.Identity.Client.OAuth2.OAuth2Client.ExecuteRequestAsync[T](Uri endPoint, HttpMethod method, RequestContext requestContext, Boolean expectErrorsOn200OK, Boolean addCommonHeaders, Func2 onBeforePostRequestData) at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger) at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger) at Microsoft.Identity.Client.OAuth2.TokenClient.SendTokenRequestAsync(IDictionary2 additionalBodyParameters, String scopeOverride, String tokenEndpointOverride, CancellationToken cancellationToken)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.SendTokenRequestAsync(IDictionary2 additionalBodyParameters, CancellationToken cancellationToken) at Microsoft.Identity.Client.Internal.Requests.ClientCredentialRequest.GetAccessTokenAsync(CancellationToken cancellationToken, ILoggerAdapter logger) at Microsoft.Identity.Client.Internal.Requests.ClientCredentialRequest.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(Func1 codeBlock)
at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.ApiConfig.Executors.ConfidentialClientExecutor.ExecuteAsync(AcquireTokenCommonParameters commonParameters, AcquireTokenForClientParameters clientParameters, CancellationToken cancellationToken)
at AzureSearch.Identity.RegionalClientCertificateCredential.<>c__DisplayClass4_0.<b__0>d.MoveNext() in F:\dbs\el\mbas\Source\Common\Product\AzureSearch.Identity\RegionalClientCertificateCredential.cs:line 69
Relevant code snippets
public sealed class RegionalClientCertificateCredential : TokenCredential
{
private readonly IConfidentialClientApplication _confidentialClient;
private readonly bool _sendCertificateChain;
public RegionalClientCertificateCredential(
string authority, string tenantId, string clientId, X509Certificate2 clientCertificate, string region, bool sendCertificateChain)
{
_confidentialClient = ConfidentialClientApplicationBuilder.Create(clientId)
.WithAuthority(authority, tenantId)
.WithCertificate(clientCertificate)
.WithAzureRegion(region)
.Build();
Log.TraceVerbose($"{nameof(RegionalClientCertificateCredential)} is initialized with azure region {region}.");
_sendCertificateChain = sendCertificateChain;
}
public override AccessToken GetToken(
TokenRequestContext requestContext, CancellationToken cancellationToken) =>
GetTokenAsync(requestContext, cancellationToken).GetAwaiter().GetResult();
public override async ValueTask<AccessToken> GetTokenAsync(
TokenRequestContext requestContext, CancellationToken cancellationToken)
{
AcquireTokenForClientParameterBuilder request = _confidentialClient.AcquireTokenForClient(requestContext.Scopes)
.WithSendX5C(_sendCertificateChain);
if (!String.IsNullOrEmpty(requestContext.TenantId))
{
request.WithTenantId(requestContext.TenantId);
}
if (!String.IsNullOrEmpty(requestContext.ParentRequestId) && Guid.TryParse(requestContext.ParentRequestId, out Guid guid))
{
request.WithCorrelationId(guid);
}
if (!String.IsNullOrEmpty(requestContext.Claims))
{
request.WithClaims(requestContext.Claims);
}
int maxRetries = 3;
AuthenticationResult result = await Retry.ExecuteAsync<AuthenticationResult,Exception>(
nameof(GetTokenAsync),
async (attempt) =>
{
Log.TraceVerbose($"Attempt {attempt}: {nameof(RegionalClientCertificateCredential)} start to acquire token for tenant \"{requestContext.TenantId}\" with parent requst ID \"{requestContext.ParentRequestId}\"");
try
{
return await request.ExecuteAsync(cancellationToken).ConfigureAwait(false);
}
catch (Exception ex)
{
Log.TraceException(ex, TraceEventType.Error, $"ERROR: {nameof(RegionalClientCertificateCredential)} acquire token for tenant \"{requestContext.TenantId}\" with parent requst ID \"{requestContext.ParentRequestId}\" failed. Exception: '{ex.GetType().FullName}' occured");
throw ex;
}
},
maxAttempts: maxRetries,
shouldRetry: ex => {
return IsMsalRetryableException(ex);
},
retryDelayEvaluator: Retry.ExponentialDelay(initialDelay: TimeSpan.FromMilliseconds(500)),
cancellationToken: cancellationToken).ConfigureAwait(false);
return new AccessToken(result.AccessToken, result.ExpiresOn);
}
//Following example from https://learn.microsoft.com/en-us/entra/msal/dotnet/advanced/exceptions/retry-policy#example-retry-policy to retry on retryable exceptions
private bool IsMsalRetryableException(Exception ex)
{
bool isRetryable = false;
if (ex is HttpRequestException)
{
isRetryable = true;
} else if (ex is MsalException msalException && msalException.IsRetryable)
{
isRetryable = true;
}
if (isRetryable)
{
Log.TraceVerbose($"Will retry accquiring token later.");
} else
{
Log.TraceVerbose($"Non-Retryable exception {ex.GetType().FullName}.");
}
return isRetryable;
}
Expected behavior
No response
Identity provider
Microsoft Entra ID (Work and School accounts and Personal Microsoft accounts)
Regression
No response
Solution and workarounds
No response
Library version used
4.66.1
.NET version
.Net6.0
Scenario
ConfidentialClient - service to service (AcquireTokenForClient)
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 have enabled ESTS-r globally. And we are seeing the following errors across the board. Can you help to take a look?
2025-04-23T12:45:47 [msg:1bd9][deq:998c] MsalUiRequiredException ERROR: RegionalClientCertificateCredential acquire token for tenant "" with parent requst ID "" failed. Exception: 'Microsoft.Identity.Client.MsalUiRequiredException' occured: AADSTS5000224: We are sorry, this resource is not available. If you are seeing this message by mistake, please contact Microsoft support. Trace ID: 22c5042e-23b3-4157-a5d5-14e787cec700 Correlation ID: 3aefdc8a-a61a-42d6-9da2-d5df9639826f Timestamp: 2025-04-23 12:45:47Z.
Stack: at Microsoft.Identity.Client.OAuth2.OAuth2Client.ThrowServerException(HttpResponse response, RequestContext requestContext)
at Microsoft.Identity.Client.OAuth2.OAuth2Client.CreateResponse[T](HttpResponse response, RequestContext requestContext)
at Microsoft.Identity.Client.OAuth2.OAuth2Client.ExecuteRequestAsync[T](Uri endPoint, HttpMethod method, RequestContext requestContext, Boolean expectErrorsOn200OK, Boolean addCommonHeaders, Func
2 onBeforePostRequestData) at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger) at Microsoft.Identity.Client.OAuth2.TokenClient.SendHttpAndClearTelemetryAsync(String tokenEndpoint, ILoggerAdapter logger) at Microsoft.Identity.Client.OAuth2.TokenClient.SendTokenRequestAsync(IDictionary2 additionalBodyParameters, String scopeOverride, String tokenEndpointOverride, CancellationToken cancellationToken)at Microsoft.Identity.Client.Internal.Requests.RequestBase.SendTokenRequestAsync(IDictionary
2 additionalBodyParameters, CancellationToken cancellationToken) at Microsoft.Identity.Client.Internal.Requests.ClientCredentialRequest.GetAccessTokenAsync(CancellationToken cancellationToken, ILoggerAdapter logger) at Microsoft.Identity.Client.Internal.Requests.ClientCredentialRequest.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(Func1 codeBlock)at Microsoft.Identity.Client.Internal.Requests.RequestBase.RunAsync(CancellationToken cancellationToken)
at Microsoft.Identity.Client.ApiConfig.Executors.ConfidentialClientExecutor.ExecuteAsync(AcquireTokenCommonParameters commonParameters, AcquireTokenForClientParameters clientParameters, CancellationToken cancellationToken)
at AzureSearch.Identity.RegionalClientCertificateCredential.<>c__DisplayClass4_0.<b__0>d.MoveNext() in F:\dbs\el\mbas\Source\Common\Product\AzureSearch.Identity\RegionalClientCertificateCredential.cs:line 69
Relevant code snippets
Expected behavior
No response
Identity provider
Microsoft Entra ID (Work and School accounts and Personal Microsoft accounts)
Regression
No response
Solution and workarounds
No response