Improve IDW10109 error handling for credential loading failures#3946
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves debuggability of IDW10109 (“No credential could be loaded”) by preserving the original credential-loading exception(s) as InnerException (or AggregateException) so callers can programmatically inspect MSAL/AADSTS failures, and removes now-redundant logging logic.
Changes:
- Preserve original credential-loading failures as
InnerExceptionwhen throwing IDW10109 fromCredentialsProvider. - Update IDW10109 text to cover signed assertion/FIC scenarios; remove dead
catchinTokenAcquisitionand an unused duplicate error constant. - Add unit tests for single vs. multiple failures; ignore repo-root
Temp/MSBuild temp output via.gitignore.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/Microsoft.Identity.Web.Test/Certificates/WithClientCredentialsTests.cs | Adds tests asserting IDW10109 preserves inner exception(s) and includes updated guidance text. |
| src/Microsoft.Identity.Web.TokenAcquisition/TokenAcquisition.cs | Removes unreachable IDW10109-specific catch/logging to avoid dead code and double logging. |
| src/Microsoft.Identity.Web.TokenAcquisition/IDWebErrorMessage.cs | Updates the IDW10109 message to cover signed assertion/FIC failures and point to inner exception details. |
| src/Microsoft.Identity.Web.TokenAcquisition/CredentialsProvider.cs | Collects credential-loading exceptions and attaches them as InnerException (or AggregateException) on IDW10109. |
| src/Microsoft.Identity.Web.Certificate/CertificateErrorMessage.cs | Removes an unused duplicate IDW10109 constant. |
| .gitignore | Ignores repo-root Temp/ directory created by newer SDK/MSBuild temp output. |
bgavrilMS
approved these changes
Jul 15, 2026
neha-bhargava
approved these changes
Jul 15, 2026
gladjohn
approved these changes
Jul 15, 2026
neha-bhargava
approved these changes
Jul 15, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When credential loading fails in
CredentialsProvider(e.g., a Federated Identity Credential exchange returns an AADSTS error), the original exception is discarded. The thrownArgumentException(IDW10109) includes the exception text in its message string but does not setInnerException, so callers cannot programmatically inspect the original error. The error text also implies the root cause is about the certificate and Managed Identity scenarios, but the exception catches a much broader range of errors (such as FIC/signed assertion scenarios).Additionally, a
catch (ArgumentException ex) when (ex.Message == ...)guard inTokenAcquisition.BuildConfidentialClientApplicationAsyncused exact string equality against an IDW10109 error message constant. BecauseCredentialsProviderappends detail text andArgumentExceptionadds a parameter name suffix, the guard never matched, making it dead code. The outercatch (Exception ex)already logs and rethrows all errors from this method, so if it wasn't dead code it'd be logged twice unnecessarily.Changes
Inner exception preservation (
CredentialsProvider.cs)Caught exceptions are now collected and passed as the
InnerExceptionwhen throwing IDW10109:InnerExceptionis the original exception directlyInnerExceptionis anAggregateExceptioncontaining all originalsUpdated error text (
IDWebErrorMessage.cs)IDW10109 now mentions FIC/signed assertion scenarios and directs developers to check the inner exception for service-level error details such as AADSTS error codes.
Removed dead catch block (
TokenAcquisition.cs)Removed the inner
catch (ArgumentException ex) when (...)block that was unreachable dead code. The outercatch (Exception ex)at the method level already provides equivalent logging viaLogger.TokenAcquisitionError.Removed unused duplicate (
CertificateErrorMessage.cs)Removed
CertificateErrorMessage.ClientCertificatesHaveExpiredOrCannotBeLoaded, a duplicate IDW10109 definition with different wording that had zero references in source..gitignore: ignore MSBuild temp filesAdded
Temp/to.gitignore. The .NET 9+ SDK writes MSBuild temp files to aTemp/folder inside the repo root, which showed up as untracked files.Tests
Two new tests in
WithClientCredentialsTests.cs:AllCredentialsFail_SingleFailure_PreservesInnerExceptionAndErrorTextMsalServiceExceptionis set asInnerExceptionwith AADSTS error code accessible; error text includes FIC guidanceAllCredentialsFail_MultipleFailures_PreservesAllExceptionsViaAggregateExceptionAggregateExceptioninner containing all original exceptions