4

We have been seeing the following stack trace in our code base:

System.ArgumentException: An item with the same key has already been added. 
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add) 
   at System.Net.Http.Headers.HttpHeaders.AddHeaderToStore(String name, HeaderStoreItemInfo info) 
   at System.Net.Http.Headers.HttpHeaders.SetParsedValue(String name, Object value) 
   at System.Net.Http.Headers.HttpContentHeaders.get_ContentLength() 
   at System.Net.Http.HttpClientHandler.PrepareAndStartContentUpload(RequestState state) 

and have narrowed it down to somewhere in our code where we call

HttpContent.ReadAsStringAsync()

When this happens, we are sure the instance of HttpContent is being used by multiple threads, all of which are somehow trying to read the actual content. Have not yet figured out how reading of the content affects the headers.

If it was possible to perform a deep clone of the HttpContent, assuming all if the content payload has been downloaded, we would have looked into this option.

Anyone run into this and if so, how did you solve it?

Thanks in advance.

Klaus Nji
  • 18,107
  • 29
  • 105
  • 185
  • Please give some repro code. This looks like you're trying to upload content and it can't add the Content-Length header for some reason, but hard to tell without more code. – Cory Nelson Nov 24 '20 at 07:13

1 Answers1

2

It makes no sense to me that your stacktrace is linked to a reading of a response. Seems more probable that before you make the request you have threads fighting to add a header. Perhaps some confusion with asynchronous debugging? I have seen this when I had a line like this (client is a HttpClient)

client.DefaultRequestHeaders.AcceptEncoding.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("gzip"));

on the code where each thread could execute this, it then became a race condition because I believe the httpclient will check existence before it adds it then if between that time two threads try to add it, it will crash out like this. Depending on your setup you may either need to move something like this into the initialization or throw a lock around it.

Ahmet Kakıcı
  • 6,294
  • 4
  • 37
  • 49
Morgeth888
  • 143
  • 2
  • 13