HttpClient request throws IOException
Asked Answered
M

3

70

The following code throws a IOException with the message: "The specified registry key does not exist."

HttpClient client = new HttpClient();

Uri uri = new Uri("http://www.google.com");

client.GetAsync(uri);

This is just in a console app in Main. It looks like the error is being thrown by mscorlib.dll!Microsoft.Win32.RegistryKey.Win32Error(int errorCode, string str). I have no idea why this error is being thrown or how to start debugging it.

Edit stack trace:

at Microsoft.Win32.RegistryKey.Win32Error(Int32 errorCode, String str)

It's just 1 line and there is no inner exxception etc..

The call stack is:

mscorlib.dll!Microsoft.Win32.RegistryKey.Win32Error(int errorCode, string str) + 0x189 bytes    
mscorlib.dll!Microsoft.Win32.RegistryKey.GetValueKind(string name) + 0x7f bytes 
System.dll!System.Net.HybridWebProxyFinder.InitializeFallbackSettings() + 0x9e bytes    
[Native to Managed Transition]  
[Managed to Native Transition]  
System.dll!System.Net.AutoWebProxyScriptEngine.AutoWebProxyScriptEngine(System.Net.WebProxy proxy, bool useRegistry) + 0xd0 bytes   
System.dll!System.Net.WebProxy.UnsafeUpdateFromRegistry() + 0x2c bytes  
System.dll!System.Net.Configuration.DefaultProxySectionInternal.DefaultProxySectionInternal(System.Net.Configuration.DefaultProxySection section) + 0x1d8 bytes 
System.dll!System.Net.Configuration.DefaultProxySectionInternal.GetSection() + 0xec bytes   
System.dll!System.Net.WebRequest.InternalDefaultWebProxy.get() + 0xcc bytes 
System.dll!System.Net.HttpWebRequest.HttpWebRequest(System.Uri uri, System.Net.ServicePoint servicePoint) + 0xdf bytes  
System.dll!System.Net.HttpWebRequest.HttpWebRequest(System.Uri uri, bool returnResponseOnFailureStatusCode, string connectionGroupName, System.Action<System.IO.Stream> resendRequestContent) + 0x2b bytes  
System.Net.Http.dll!System.Net.Http.HttpClientHandler.CreateAndPrepareWebRequest(System.Net.Http.HttpRequestMessage request) + 0x59 bytes   
System.Net.Http.dll!System.Net.Http.HttpClientHandler.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + 0xf4 bytes  
System.Net.Http.dll!System.Net.Http.HttpMessageInvoker.SendAsync(System.Net.Http.HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) + 0x4f bytes 
System.Net.Http.dll!System.Net.Http.HttpClient.SendAsync(System.Net.Http.HttpRequestMessage request, System.Net.Http.HttpCompletionOption completionOption, System.Threading.CancellationToken cancellationToken) + 0x13e bytes 
System.Net.Http.dll!System.Net.Http.HttpClient.GetAsync(System.Uri requestUri, System.Net.Http.HttpCompletionOption completionOption) + 0xc bytes   

ConsoleServiceTest.exe!ConsoleServiceTest.Program.Main(string[] args) Line 20 + 0x17 bytes  C#
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x5a bytes  
    mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x285 bytes 
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x9 bytes   
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x57 bytes    
    mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x51 bytes   
    [Native to Managed Transition]  
Mclendon answered 30/10, 2012 at 14:43 Comment(5)
What's the entire stack trace?Editheditha
What is the HResult on that IOException? It sort of looks like your process lacks access to the IE Proxy information in the registry.Quiteri
HResult is 2, not too sure what that means!Mclendon
Looks like it opens HKCU but has no access. Out of curiosity, do you have a PAC file or something set in your Proxy Settings? And does this go away if you uncheck "Autodetect Proxy Settings".Quiteri
I personally haven't set up anything like that. Not sure if anything from my companies network setup is setting something....In internet options the LAN settings are set to automatically detect and I still get the exception if I uncheck autodetect.Mclendon
T
85

It seems that this is caused by a recent security update for the .NET Framework: MS12-074: Vulnerabilities in .NET Framework could allow remote code execution: November 13, 2012 (KB 2745030)

It all boils down to the following code in the web proxy resolution:

[RegistryPermission(SecurityAction.Assert, Read=@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework")]
private static void InitializeFallbackSettings()
{
    allowFallback = false;
    try
    {
        using (RegistryKey key = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\.NETFramework"))
        {
            try
            {
                if (key.GetValueKind("LegacyWPADSupport") == RegistryValueKind.DWord)
                {
                    allowFallback = ((int) key.GetValue("LegacyWPADSupport")) == 1;
                }
            }
            catch (UnauthorizedAccessException)
            {
            }
            catch (IOException)
            {
            }
        }
    }
    catch (SecurityException)
    {
    }
    catch (ObjectDisposedException)
    {
    }
}

As you can see it checks for a specific registry key mentioned in the KB article. Also you should note that the exception is caught internally, but you see it because you have enabled First Chance Exceptions in the debug options of Visual Studio.

If you want to not see this exception you should add the specified registry key with value 0:

Registry location: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework  
DWORD (32-bit) Value name: LegacyWPADSupport
Value data: 0

and for 32-bit processes on 64-bit machines:

Registry location: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework
DWORD (32-bit) Value name: LegacyWPADSupport
Value data: 0
Turpentine answered 20/11, 2012 at 10:7 Comment(3)
Found the update on my Windows 7 64 bit box had been applied as KB2729449. Relevant KB for other systems should be found here technet.microsoft.com/en-us/security/bulletin/ms12-074 Adding LegacyWPADSupport to registry worked.Petua
On my machine, it was looking for the key under HKLM\SOFTWARE\Microsoft\.NETFramework and I'm running 64 bit Win 7.Psychosis
@rstackhouse: right. I've amended the answer. The Wow6432Node is only relevant if you're running a 32-bit process on your 64-bit OS.Dialectical
R
28

I agree with Ligaz's answer, and I've logged a Connect issue about this bug: https://connect.microsoft.com/VisualStudio/feedback/details/773666/webrequest-create-eats-an-ioexception-on-the-first-call#details

Save the following into a .reg file and import it into the registry to prevent this error from being raised:

Windows Registry Editor Version 5.00

; The following value prevents an IOException from being thrown and caught
; by System.Net.HybridWebProxyFinder.InitializeFallbackSettings() (in System.dll)
; when WebRequest.Create is first called.  By default the "LegacyWPADSupport"
; value doesn't exist, and when InitializeFallbackSettings calls GetValueKind,
; an IOException is thrown.  This adds the value with its default of false to
; prevent the exception.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework]
"LegacyWPADSupport"=dword:00000000

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework]
"LegacyWPADSupport"=dword:00000000
Rooke answered 6/12, 2012 at 14:24 Comment(1)
Notice that the access to the connect url mention requires a Microsoft account. Thank you for having informed on this publicly readable site.Smokechaser
Q
10

For whatever reason, your HttpClient code is looking for proxy settings in the registry and cannot open the key. A look through the code shows that it attempts to open HKCU and then go to one of the following keys in order:

  1. "HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections"
  2. "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Connections"
  3. "HKLM\\SOFTWARE\\Policies\\Microsoft\\Windows\\CurrentVersion\\Internet Settings"

One of these three is potentially the key your process has no access to, why I am not sure. One possible fix is to disable Automatically Detect Proxy Settings.

Otherwise, you'll need to figure out exactly what key it is loading and we'll do that with two steps.

  1. Enable System.Net logging.
  2. Download and run Procmon, filtering on registry access for your application, like so:
  1. Once opened, disable capturing if enabled (the magnifying glass should have a red X through it).enter image description here
  2. Start filtering on your processes name.enter image description here
  3. Unselect all options except Registry Entries

enter image description here

  1. Enable capturing (click the magnifying glass)
  2. Run your application
  3. Find the offending entry in the log, double click to see which key it was opening

Once you determine the offending key, you can work to figure out why your application does not have access to it. Perhaps, if the name of your application is any indication, the user account your service is running under lacks access to the registry key.

Quiteri answered 30/10, 2012 at 15:32 Comment(11)
Result for HKLM\SOFTWARE\Microsoft\.NETFramework\LegacyWPADSupport is NAME NOT FOUND. That is the last entry in proc mon logMclendon
This key isn't in my registry, so it isn't a permission issue.Mclendon
Did adding a key by that name help?Quiteri
It got rid of the IOException. Now i'm receiving a SocketException with the message "An attempt was made to access a socket in a way forbidden by its access permissions 10.34.5.92:80"Mclendon
This answer seems to suggest a firewall is blocking the socket.Quiteri
I have given this app permission in windows firewall and I am still receiving this exception. I am running windows 8 and i'm starting to think this is an issue specific to that. I have run this code on windows 7 on the same network with no issuesMclendon
I think it may be a framework version issue, but regardless I'd add a new question (something along the lines of "socketexception with httpclient on windows 8 yada yada yada").Quiteri
I'm having the exact same issue. Recently switched to Windows 8, and not having this on any 7 machine.Warnke
If your developing a winrt app you need to set the permission in the package manifest fileMclendon
Mine is a .NET 4 WPF desktop app. Perhaps this has been fixed in 4.5.. I'll test.Warnke
I added the key for the 64-bit machine and it solved my problem. ThanksArlenarlena

© 2022 - 2024 — McMap. All rights reserved.