{"record":{"id":"487add2fe90ed443","repo":"jstedfast/MailKit","slug":"the-specified-host-address-must-be-ipv4","errorCode":null,"errorMessage":"The specified host address must be IPv4.","messagePattern":"The specified host address must be IPv4\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"MailKit/Net/Proxy/Socks4Client.cs","lineNumber":241,"sourceCode":"\t\t/// </exception>\n\t\tpublic override Stream Connect (string host, int port, CancellationToken cancellationToken = default)\n\t\t{\n\t\t\tbyte[]? domain = null;\n\t\t\tbyte[] addr;\n\n\t\t\tValidateArguments (host, port);\n\n\t\t\tif (!IPAddress.TryParse (host, out var ip)) {\n\t\t\t\tif (IsSocks4a) {\n\t\t\t\t\tdomain = Encoding.UTF8.GetBytes (host);\n\t\t\t\t\taddr = InvalidIPAddress;\n\t\t\t\t} else {\n\t\t\t\t\tip = Resolve (host, cancellationToken);\n\t\t\t\t\taddr = ip.GetAddressBytes ();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (ip.AddressFamily != AddressFamily.InterNetwork)\n\t\t\t\t\tthrow new ArgumentException (\"The specified host address must be IPv4.\", nameof (host));\n\n\t\t\t\taddr = ip.GetAddressBytes ();\n\t\t\t}\n\n\t\t\tcancellationToken.ThrowIfCancellationRequested ();\n\n\t\t\tvar socket = SocketUtils.Connect (ProxyHost, ProxyPort, LocalEndPoint, cancellationToken);\n\n\t\t\ttry {\n\t\t\t\tvar buffer = GetConnectCommand (domain, addr, port);\n\n\t\t\t\tSend (socket, buffer, 0, buffer.Length, cancellationToken);\n\n\t\t\t\t// +-----+-----+----------+----------+\n\t\t\t\t// | VER | REP | BND.PORT | BND.ADDR |\n\t\t\t\t// +-----+-----+----------+----------+\n\t\t\t\t// |  1  |  1  |    2     |    4     |\n\t\t\t\t// +-----+-----+----------+----------+","sourceCodeStart":223,"sourceCodeEnd":259,"githubUrl":"https://github.com/jstedfast/MailKit/blob/9d3859a7855e3e17582c07fd01972b8e262bf176/MailKit/Net/Proxy/Socks4Client.cs#L223-L259","documentation":"When Socks4Client.Connect is given an IPAddress directly instead of a host name, it requires AddressFamily.InterNetwork; an IPv6 address throws ArgumentException('The specified host address must be IPv4.'). SOCKS4 protocol cannot carry IPv6 addresses.","triggerScenarios":"Calling Socks4Client.Connect passing an IPEndPoint/IPAddress built from an IPv6 literal (e.g. ::1 or a resolved AAAA address) — for instance IPAddress.IPv6Loopback or the result of DNS.GetHostAddresses picking the v6 entry.","commonSituations":"Hard-coding 'localhost' and using IPAddress.Parse(\"::1\") or Dns resolution returning ::1; test code constructing endpoints with Any/IPv6Any; migrating code from Socks5 (IPv6-capable) to Socks4 without updating addresses.","solutions":["Pass an IPv4 IPAddress or literal (e.g. 127.0.0.1, not ::1).","Filter resolved addresses for AddressFamily.InterNetwork before passing one in.","Use Socks5Client if the target is only reachable over IPv6.","Replace the IPv6 loopback with IPAddress.Loopback (127.0.0.1) in tests."],"exampleFix":"// before\nvar proxy = new Socks4Client();\nproxy.Connect(new IPEndPoint(IPAddress.Parse(\"::1\"), 995), \"user\"); // IPv6 -> throws\n// after\nproxy.Connect(new IPEndPoint(IPAddress.Loopback, 995), \"user\"); // 127.0.0.1","handlingStrategy":"validation","validationCode":"if (ip.AddressFamily != AddressFamily.InterNetwork)\n    throw new InvalidOperationException($\"SOCKS4 requires IPv4, got {ip}\");","typeGuard":"bool IsIPv4(IPAddress ip) => ip.AddressFamily == AddressFamily.InterNetwork;","tryCatchPattern":"try {\n    proxy.Connect(new IPEndPoint(ip, port), cancellationToken);\n} catch (ArgumentException ex) when (ex.Message.Contains(\"must be IPv4\")) {\n    // resolve/select an IPv4 address or use Socks5Client\n}","preventionTips":["Never use IPAddress.IPv6Loopback/::1 with SOCKS4 — use 127.0.0.1","Pick addresses with AddressFamily.InterNetwork when iterating DNS results","Migrate to Socks5Client for any IPv6-only destination"],"tags":["socks4","ipv4","proxy","argument-validation","mailkit"],"backgroundTag":"invalid-argument-value","analyzedSha":"9d3859a7855e3e17582c07fd01972b8e262bf176","analyzedAt":"2026-09-15T15:46:11.592Z","contentChangedAt":"2026-09-15T15:46:11.592Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}