question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Exception: AcquireTokenSilentAsync An item with the same key has already been added. Key: User-Agent

See original GitHub issue

Which Version of MSAL are you using ? MSAL 2.2.1-preview

Which platform has the issue? Xamarin Android

What authentication flow has the issue?

  • Desktop
    • Interactive
    • Integrated Windows Auth
    • Username / Password
    • Device code flow (browserless)
  • Mobile
  • Web App
    • Authorization code
    • OBO
  • Web API
    • OBO

Repro I have a Xamarin forms application - users have accounts on Azure AD B2C. I am using this library to authenticate the user and get a token to pass on to my WebApi. It works really well. However I am seeing an exception randomly when I call AcquireTokenSilentAsync.

I have a service class where I have placed all my web calls - so everything that needs access to the API is using this code. I have background threads and button events which call this function.

Issue appears to happen most on app resume/startup when my app will make 2 calls to the API (one of which is running a separate thread). In most cases - one of them succeeds, and one fails with the exception. An item with the same key has already been added. Key: User-Agent. Should I just retry the failed one in the hope it passes the next time? Or is there something extra I need to do?

Here is my code:

`public async Task<T> GetSecureAsync<T>(string apiUrl, bool forceRefreshToken = false)
        {
            try
            {
                AuthenticationResult ar = null;
                
                try
                {
                    var accounts = await App.AuthenticationClient.GetAccountsAsync();
                    ar = await App.AuthenticationClient.AcquireTokenSilentAsync(ApplicationSettings.Scopes, accounts.FirstOrDefault());//, ApplicationSettings.Authority, forceRefreshToken);
                }
                catch (Exception ex)
                {
                    LogException(ex, nameof(GetSecureAsync), typeof(Client).ToString());
                }
                
                if (ar != null)
                {//use token and call API
                    using (HttpClient client = new HttpClient(new NativeMessageHandler() { Timeout = TimeSpan.FromMilliseconds(30000) }))
                    {`

Expected behavior User should be authenticated if a token exists in cache for them - an AuthenticationResult should be returned.

Actual behavior An exception is thrown: An item with the same key has already been added. Key: User-Agent

Additional context/ Logs / Screenshots Here is the stack trace of the exception:

System.Collections.Generic Dictionary2[TKey,TValue].TryInsert (TKey key, TValue value, System.Collections.Generic.InsertionBehavior behavior) System.Collections.Generic Dictionary2[TKey,TValue].Add (TKey key, TValue value) System.Net.Http.Headers HttpHeaders.GetValues[T] (System.String name) System.Net.Http.Headers HttpRequestHeaders.get_UserAgent () Microsoft.Identity.Core.Http HttpManager+<ExecuteAsync>d__9.MoveNext () System.Runtime.CompilerServices TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) System.Runtime.CompilerServices ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () Microsoft.Identity.Core.Http HttpManager+<ExecuteWithRetryAsync>d__8.MoveNext () System.Runtime.CompilerServices TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) System.Runtime.CompilerServices ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () Microsoft.Identity.Core.Http HttpManager+<SendGetAsync>d__5.MoveNext () System.Runtime.CompilerServices TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) System.Runtime.CompilerServices ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () Microsoft.Identity.Core.Http HttpRequest+<SendGetAsync>d__3.MoveNext () System.Runtime.CompilerServices TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) System.Runtime.CompilerServices ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () Microsoft.Identity.Core.OAuth2 OAuth2Client+<ExecuteRequestAsync>d__81[T].MoveNext () System.Runtime.CompilerServices TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) System.Runtime.CompilerServices ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () Microsoft.Identity.Core.OAuth2 OAuth2Client+<DiscoverAadInstanceAsync>d__6.MoveNext () System.Runtime.CompilerServices TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) System.Runtime.CompilerServices ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () Microsoft.Identity.Core.Instance AadInstanceDiscovery+<SendInstanceDiscoveryRequestAsync>d__10.MoveNext () System.Runtime.CompilerServices TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) System.Runtime.CompilerServices ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () Microsoft.Identity.Core.Instance AadInstanceDiscovery+<DoInstanceDiscoveryAndCacheAsync>d__9.MoveNext () System.Runtime.CompilerServices TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) System.Runtime.CompilerServices ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () Microsoft.Identity.Core.Instance AadInstanceDiscovery+<GetMetadataEntryAsync>d__5.MoveNext () System.Runtime.CompilerServices TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) System.Runtime.CompilerServices ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () Microsoft.Identity.Client TokenCache+<GetCachedOrDiscoverAuthorityMetaDataAsync>d__42.MoveNext () System.Runtime.CompilerServices TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) System.Runtime.CompilerServices ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () Microsoft.Identity.Client TokenCache+<GetAccountsAsync>d__46.MoveNext () System.Runtime.CompilerServices TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) System.Runtime.CompilerServices ConfiguredTaskAwaitable1+ConfiguredTaskAwaiter[TResult].GetResult () Microsoft.Identity.Client ClientApplicationBase+<GetAccountsAsync>d__33.MoveNext () System.Runtime.CompilerServices TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) System.Runtime.CompilerServices TaskAwaiter1[TResult].GetResult () MyApp.Services Client+<GetSecureAsync>d__0`1[T].MoveNext

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:8

github_iconTop GitHub Comments

1reaction
WilliamWatterson86commented, Nov 6, 2018

I think so yes, I put a call to GetAccountsAsync after I initalise the Public Client Applocation and it seems to work. Happy to close

0reactions
jennyf19commented, Nov 6, 2018

awesome…thanks for getting back so quickly @WilliamWatterson86 If you run into any more issues, please open another issue. thanks. I’ll update the wiki as well, for others who run into this issue.

Read more comments on GitHub >

github_iconTop Results From Across the Web

An item with the same key has already been added
An item with the same key has already been added. And the exception details: [ArgumentException: An item with the same key has already...
Read more >
Azure Active Directory Connect - "An item with the same ...
I was performing an installation of Azure Active Directory Connect ... ArgumentException: An item with the same key has already been added.
Read more >
Error "An item with the same key has already been added"
This article helps to fix the error "An item with the same key has already been added". Applies to: Windows Server 2012 R2...
Read more >
Accessing Azure AD protected resources using OpenID ...
Now the problem is that Azure AD has its own dialect as it requires a resource parameter being added to requests to its...
Read more >
Understanding the AcquireTokenAsync API
Learn how to acquire tokens silently in public and confidential client applications using MSAL.NET.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found