Skip to content

SendTo*** and Receive(Message)From*** throw different exceptions when remoteEP AddressFamily does not match #47772

Description

@antonfirsov

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:

if (!CanTryAddressFamily(remoteEP.AddressFamily))
{
throw new ArgumentException(SR.Format(SR.net_InvalidEndPointAddressFamily,
remoteEP.AddressFamily, _addressFamily), nameof(remoteEP));
}

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.

Activity

  1. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Feb 2, 2021
  2. geoffkizer commented on Feb 3, 2021

    @geoffkizer
    Contributor

    I agree, we should change for consistency.

    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.

  3. ManickaP commented on Feb 18, 2021

    @ManickaP
    Member

    Triage: we should fix for 6.0.

  4. removed
    untriagedNew issue has not been triaged by the area owner
    on Feb 18, 2021
  5. added this to the 6.0.0 milestone on Feb 18, 2021
  6. karelz commented on May 13, 2021

    @karelz
    Member

    Triage: UDP corner case, fine to move to Future.

  7. modified the milestones: 6.0.0, Future on May 13, 2021
  8. added
    help wanted[up-for-grabs] Good issue for external contributors
    on Jan 25, 2023
  9. caraioniurie47 commented on Oct 9, 2026

    @caraioniurie47
    Contributor

    Summary

    • 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 main bb31474ef5f; 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.

    Source

    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.

  10. added
    in-prThere is an active PR which will close this issue when it is merged
    on Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-System.Net.Socketsbughelp wanted[up-for-grabs] Good issue for external contributorsin-prThere is an active PR which will close this issue when it is merged

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions