runtime: HttpClient.GetAsync/PostAsync sets different error code on SocketException on Windows 7 when host could not be resolved
On all platforms except Windows 7 when host name could not be resolved we get HttpRequestException
with inner SocketException
with SocketException.SocketErrorCode
set to SocketError.HostNotFound
while on Windows 7 we get SocketErrorCode.NoData
.
This is problematic in Wcf scenarios where they wrap our exception and would like to throw System.ServiceModel.EndpointNotFoundException
but the inconsistency makes it more difficult.
Simple repro is (PostAsync has identical result):
var r = (new HttpClient()).GetAsync("http://nonexistenthostname/foo/bar").Result;
Here is the exact exception being thrown on Windows7
System.AggregateException : One or more errors occurred. (The requested name is valid, but no data of the requested type was found)
---- System.Net.Http.HttpRequestException : The requested name is valid, but no data of the requested type was found
-------- System.Net.Sockets.SocketException : The requested name is valid, but no data of the requested type was found
Stack Trace:
E:\A\_work\104\s\src\mscorlib\src\System\Threading\Tasks\future.cs(493,0): at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
C:\Users\dotnet-bot\Desktop\src\corefx\src\System.Net.Http\tests\FunctionalTests\HttpClientHandlerTest.cs(3180,0): at System.Net.Http.Functional.Tests.HttpClientHandlerTest.HttpClientNonExistingHostnameTest()
----- Inner Stack Trace -----
C:\Users\dotnet-bot\Desktop\src\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\ConnectHelper.cs(86,0): at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
E:\A\_work\104\s\src\mscorlib\shared\System\Threading\Tasks\ValueTask.cs(723,0): at System.Threading.Tasks.ValueTask`1.get_Result()
C:\Users\dotnet-bot\Desktop\src\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnectionPool.cs(338,0): at System.Net.Http.HttpConnectionPool.CreateConnectionAsync(HttpRequestMessage request, CancellationToken cancellationToken)
E:\A\_work\104\s\src\mscorlib\shared\System\Threading\Tasks\ValueTask.cs(723,0): at System.Threading.Tasks.ValueTask`1.get_Result()
C:\Users\dotnet-bot\Desktop\src\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnectionPool.cs(480,0): at System.Net.Http.HttpConnectionPool.WaitForCreatedConnectionAsync(ValueTask`1 creationTask)
E:\A\_work\104\s\src\mscorlib\shared\System\Threading\Tasks\ValueTask.cs(723,0): at System.Threading.Tasks.ValueTask`1.get_Result()
C:\Users\dotnet-bot\Desktop\src\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\HttpConnectionPool.cs(271,0): at System.Net.Http.HttpConnectionPool.SendWithRetryAsync(HttpRequestMessage request, Boolean doRequestAuth, CancellationToken cancellationToken)
C:\Users\dotnet-bot\Desktop\src\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\RedirectHandler.cs(30,0): at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
C:\Users\dotnet-bot\Desktop\src\corefx\src\System.Net.Http\src\System\Net\Http\HttpClient.cs(479,0): at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)
----- Inner Stack Trace -----
C:\Users\dotnet-bot\Desktop\src\corefx\src\System.Net.Http\src\System\Net\Http\SocketsHttpHandler\ConnectHelper.cs(67,0): at System.Net.Http.ConnectHelper.ConnectAsync(String host, Int32 port, CancellationToken cancellationToken)
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 16 (16 by maintainers)
After researching this, it is valid for a SocketException to have SocketErrorCode of either HostNotFound or NoData values for “host not found” scenarios.
We actually test for this: https://github.com/dotnet/corefx/blob/2e82c748da654905e29609804393e028a06d78fa/src/System.Net.Sockets/tests/FunctionalTests/DnsEndPointTest.cs#L67
The recommendation is for WCF to change their code and add a check for
SocketErrorCode.NoData
in addition to their current check forSocketErrorCode.HostNotFound
:See: https://github.com/dotnet/wcf/blob/46f14d00bfaed9bcb3867e09073e9ac52592079c/src/System.Private.ServiceModel/src/System/ServiceModel/Channels/HttpChannelHelpers.cs#L142
It would have different behavior because .NET Core 2.0 would use a different HTTP stack (WinHTTP) on Windows.
If this ends up working ok on Win7 with .NET Core 2.0 but broken on Win7 with .NET Core 2.1, then this would be an app-compat behavior difference (due to using the new SocketsHttpHandler by default). So, we should consider that as part of triaging this issue.