You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
SendTo*** and Receive(Message)From*** throw different exceptions when remoteEP AddressFamily does not match #47772
If the address family of the remoteEP argument does not match the socket's address family, variants of Receive(Message)From throw an ArgumentException thanks to this guard:
SendTo has the same limitation, but we do not guard those methods, instead we let the underlying PAL to fail with a SocketError.InvalidArgument. We may want to change this behavior for consistency.
Also note that the Recive(Message)From exception is undocumented.
In general it seems better to be throwing ArgumentException or similar in these cases, since it represents a usage error, as opposed to SocketException which could indicate a variety of different issues.
On .NET 10.0.12, every SendTo path measured with an IPEndPoint of the wrong address family still fails with a socket error rather than ArgumentException, and the SocketErrorCode depends on the socket's family and the OS: AddressFamilyNotSupported for an IPv4 socket, but Fault (Windows) or NetworkUnreachable (Linux) for an IPv6 socket with DualMode = false. Both ReceiveFrom overloads measured throw ArgumentException in both cases.
The proposed fix: the same CanTryAddressFamily check the receive side uses, in the SendTo paths that take an EndPoint, plus a dotnet-api-docs PR documenting the ArgumentException. That check lets IPv4 endpoints through on a dual-mode socket.
It is a breaking change: ArgumentException does not derive from SocketException, so breaking-change-rules.md doesn't allow it. With the guard, the task overloads would throw instead of returning a faulted task, BeginSendTo would throw instead of EndSendTo, and SendToAsync(SocketAsyncEventArgs) would throw instead of setting e.SocketError. DualModeSocketTest.cs asserts today's SocketException.
The SocketAddress overloads should stay out of scope.
Source read at mainbb31474ef5f; the codes are measured (method in the note), what the guard would change is read from the source.
Proposal
The fix: the guard in the sync, APM and SendToAsync paths, the existing DualMode test updated, and mismatch tests in SendTo.cs mirroring the AddressFamilyDoesNotMatch_Throws_ArgumentException tests in ReceiveFrom.cs; then a dotnet-api-docs PR documenting the ArgumentException on the EndPoint send and receive overloads. As a breaking change, the fix would start with the issue breaking-change-process.md asks for.
Dropped: documenting the current behaviour instead, which would leave the asymmetry this issue reports.
Is the fix still wanted? If so, I'll implement it as above. Could this be assigned to me?
What happens today
UDP sockets, loopback destinations; the send EndPoint overloads were also run on a dual-mode IPv6 socket with an IPv4 endpoint, and succeeded.
Case
Windows 11
Ubuntu 22.04 (WSL2)
IPv4 socket, IPv6 endpoint
AddressFamilyNotSupported (10047)
AddressFamilyNotSupported (97)
IPv6 socket, DualMode = false, IPv4 endpoint
Fault (10014)
NetworkUnreachable (101)
The same code came back from SendTo(byte[], EndPoint), SendTo(ReadOnlySpan<byte>, SocketFlags, EndPoint), two SendToAsync(..., EndPoint) tasks (faulted, not thrown), EndSendTo, and SendToAsync(SocketAsyncEventArgs) (as e.SocketError, no exception). ReceiveFrom and ReceiveFromAsync(Memory<byte>, EndPoint) threw ArgumentException synchronously in both rows on both OSes.
DualModeSocketTest.cs:866 expects SocketException from SendTo on an IPv6 socket with DualMode = false and an IPv4 endpoint; :982 expects ArgumentException from ReceiveFrom in the same setup.
The receive-side SocketAddress overload checks only the size. The send-side one skips the IPv4-to-IPv6 mapping the EndPoint overloads apply on a dual-mode socket, so an IPv4 address that CanTryAddressFamily accepts would reach the OS unmapped. The guard doesn't fit these overloads.
Note
AI-generated, written at my direction and reviewed by me before posting. Source read at dotnet/runtime bb31474ef5f. The codes come from a console app built for net10.0, run on .NET 10.0.12 on Windows 11 (build 26200) and self-contained linux-x64 on Ubuntu 22.04 under WSL2; no repo build or test run.
Activity
geoffkizer commentedon Feb 3, 2021
I agree, we should change for consistency.
In general it seems better to be throwing
ArgumentExceptionor similar in these cases, since it represents a usage error, as opposed toSocketExceptionwhich could indicate a variety of different issues.ManickaP commentedon Feb 18, 2021
Triage: we should fix for 6.0.
karelz commentedon May 13, 2021
Triage: UDP corner case, fine to move to Future.
caraioniurie47 commentedon Oct 9, 2026
Summary
SendTopath measured with anIPEndPointof the wrong address family still fails with a socket error rather thanArgumentException, and theSocketErrorCodedepends on the socket's family and the OS:AddressFamilyNotSupportedfor an IPv4 socket, butFault(Windows) orNetworkUnreachable(Linux) for an IPv6 socket withDualMode = false. BothReceiveFromoverloads measured throwArgumentExceptionin both cases.CanTryAddressFamilycheck the receive side uses, in theSendTopaths that take anEndPoint, plus a dotnet-api-docs PR documenting theArgumentException. That check lets IPv4 endpoints through on a dual-mode socket.ArgumentExceptiondoes not derive fromSocketException, sobreaking-change-rules.mddoesn't allow it. With the guard, the task overloads would throw instead of returning a faulted task,BeginSendTowould throw instead ofEndSendTo, andSendToAsync(SocketAsyncEventArgs)would throw instead of settinge.SocketError.DualModeSocketTest.csasserts today'sSocketException.SocketAddressoverloads should stay out of scope.Source read at
mainbb31474ef5f; the codes are measured (method in the note), what the guard would change is read from the source.Proposal
The fix: the guard in the sync, APM and
SendToAsyncpaths, the existing DualMode test updated, and mismatch tests inSendTo.csmirroring theAddressFamilyDoesNotMatch_Throws_ArgumentExceptiontests inReceiveFrom.cs; then a dotnet-api-docs PR documenting theArgumentExceptionon theEndPointsend and receive overloads. As a breaking change, the fix would start with the issuebreaking-change-process.mdasks for.Dropped: documenting the current behaviour instead, which would leave the asymmetry this issue reports.
Is the fix still wanted? If so, I'll implement it as above. Could this be assigned to me?
What happens today
UDP sockets, loopback destinations; the send
EndPointoverloads were also run on a dual-mode IPv6 socket with an IPv4 endpoint, and succeeded.AddressFamilyNotSupported(10047)AddressFamilyNotSupported(97)DualMode = false, IPv4 endpointFault(10014)NetworkUnreachable(101)The same code came back from
SendTo(byte[], EndPoint),SendTo(ReadOnlySpan<byte>, SocketFlags, EndPoint), twoSendToAsync(..., EndPoint)tasks (faulted, not thrown),EndSendTo, andSendToAsync(SocketAsyncEventArgs)(ase.SocketError, no exception).ReceiveFromandReceiveFromAsync(Memory<byte>, EndPoint)threwArgumentExceptionsynchronously in both rows on both OSes.Source
ValidateReceiveFromEndpointAndStateandReceiveFromAsync(SocketAsyncEventArgs)checkCanTryAddressFamily.SendTo(byte[], ...),SendTo(ReadOnlySpan<byte>, ...)andSendToAsync(SocketAsyncEventArgs)serialize the endpoint with no family check;BeginSendToand the task overloads reach the last of these.DualModeSocketTest.cs:866expectsSocketExceptionfromSendToon an IPv6 socket withDualMode = falseand an IPv4 endpoint;:982expectsArgumentExceptionfromReceiveFromin the same setup.SocketAddressoverload checks only the size. The send-side one skips the IPv4-to-IPv6 mapping theEndPointoverloads apply on a dual-mode socket, so an IPv4 address thatCanTryAddressFamilyaccepts would reach the OS unmapped. The guard doesn't fit these overloads.Note
AI-generated, written at my direction and reviewed by me before posting. Source read at dotnet/runtime
bb31474ef5f. The codes come from a console app built fornet10.0, run on .NET 10.0.12 on Windows 11 (build 26200) and self-containedlinux-x64on Ubuntu 22.04 under WSL2; no repo build or test run.Align SendTo tests with receive-side address family validation (dotne…