Docker .NET HTTPClient cannot assign requested address when host times out
- [x] This is a bug report
- [ ] This is a feature request
- [x] I searched existing issues before opening this one
Expected behavior
When connecting to a host on a port behind a firewall using HTTPClient in a Docker Linux container via .NET (eg. http://google.com:8089), the request should time out and raise the following exception:
An unhandled exception of type 'System.Net.Http.HttpRequestException' occurred in System.Private.CoreLib.dll
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
Actual behavior
An unhandled exception of type 'System.Net.Http.HttpRequestException' occurred in System.Private.CoreLib.dll: 'Cannot assign requested address'
Stack trace:
> at System.Net.Http.ConnectHelper.<ConnectAsync>d__1.MoveNext()
> at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
> at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
> at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
> at System.Threading.Tasks.ValueTask`1.get_Result()
> at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult()
Since Docker sits between the Linux kernel and the connect() call, the assumption is that the execution flow is something like this:
- you attempt to make a request with C#'s HTTPClient
- it calls the UNIX socket function connect()
- the Linux kernel handles the connection
- if the request takes too long to execute, it's cancelled by the kernel
- Docker sees the kernel failed the connect() call
Therefore, Docker returns an error that it couldn't assign an address because it thinks the kernel refused an address:port assignment.
Setting the HTTPClient timeout to lower than the kernel limit to something like TimeSpan.FromSeconds(15) correctly raises a TaskCanceledException and not "cannot assign requested address".
Note: This issue does not exist when using Windows Containers. In addition, it does not occur when using barebones C to execute the same network request in a Linux container. It seems to be an issue with Docker and .NET.
Steps to reproduce the behavior
.Net Core Console application:
class Program
{
static async Task Main(string[] args)
{
var client = new HttpClient();
var result = await client.GetAsync("http://google.com:8089");
}
}
Auto-Generated Dockerfile in Visual Studio:
FROM mcr.microsoft.com/dotnet/core/runtime:3.1-buster-slim AS base
WORKDIR /app
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["ConsoleApp1/ConsoleApp1.csproj", "ConsoleApp1/"]
RUN dotnet restore "ConsoleApp1/ConsoleApp1.csproj"
COPY . .
WORKDIR "/src/ConsoleApp1"
RUN dotnet build "ConsoleApp1.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "ConsoleApp1.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ConsoleApp1.dll"]
Output of docker version:
Client: Docker Engine - Community
Version: 19.03.12
API version: 1.40
Go version: go1.13.10
Git commit: 48a66213fe
Built: Mon Jun 22 15:43:18 2020
OS/Arch: windows/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.12
API version: 1.40 (minimum version 1.12)
Go version: go1.13.10
Git commit: 48a66213fe
Built: Mon Jun 22 15:49:27 2020
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v1.2.13
GitCommit: 7ad184331fa3e55e52b890ea95e65ba581ae3429
runc:
Version: 1.0.0-rc10
GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd
docker-init:
Version: 0.18.0
GitCommit: fec3683
Output of docker info:
Client:
Debug Mode: false
Server:
Containers: 2
Running: 1
Paused: 0
Stopped: 1
Images: 36
Server Version: 19.03.12
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
Volume: local
Network: bridge host ipvlan macvlan null overlay
Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429
runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd
init version: fec3683
Security Options:
seccomp
Profile: default
Kernel Version: 4.19.76-linuxkit
Operating System: Docker Desktop
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 1.945GiB
Name: docker-desktop
ID: 4VOY:AZUQ:HI5H:JJIK:XUL7:6B6B:DXFE:4WDO:ZVTE:CHIP:JZQV:GZQD
Docker Root Dir: /var/lib/docker
Debug Mode: true
File Descriptors: 46
Goroutines: 55
System Time: 2020-07-29T16:27:50.516631058Z
EventsListeners: 3
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
127.0.0.0/8
Live Restore Enabled: false
Product License: Community Engine
Did you ever figure this out?
@BainsDev @Darkatek7 got the same problem. Did you found anything ?
Same problem for me in year 2024 :)