jstedfast/MailKit · error · ProxyProtocolException
Failed to connect to
Error message
Failed to connect to {0}:{1}: {2} What it means
After sending the SOCKS4 CONNECT request, Socks4Client reads the 8-byte reply and requires byte[1] == 0x5A (RequestGranted). Any other reply code throws ProxyProtocolException('Failed to connect to host:port: <reason>') where the reason names the SOCKS4 failure (request rejected/ident failed, target unreachable, etc.).
Solutions
- Check the failure reason embedded in the exception message (GetFailureReason output) for the exact SOCKS4 reply code.
- Verify the proxy allows CONNECT to the target host:port and add the ACL entry if not.
- Supply the correct SOCKS4 userid in the Connect call if the proxy validates ident.
- Confirm the endpoint really is a SOCKS4 proxy; use Socks5Client/HttpProxyClient if it is SOCKS5/HTTP.
- Test manually: `curl --socks4 proxy:1080 http://target:port` to reproduce outside the app.
Example fix
// before
var proxy = new Socks4Client("proxy.corp", 1080);
proxy.Connect(targetEp); // rejected: ACL blocks port 995
// after
// fix on proxy side: allow CONNECT to target:995, or use an allowed proxy
var proxy = new Socks4Client("proxy-alt.corp", 1080);
proxy.Connect(targetEp, "socksUserId"); Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight the proxy path outside the app: // curl --socks4 proxy:1080 https://target:port -I
Try / catch
try {
return proxy.Connect(targetEp, cancellationToken);
} catch (ProxyProtocolException ex) when (ex.Message.Contains("Failed to connect to")) {
// message carries the SOCKS4 reply reason: check ACLs/userid/proxy type
throw new InvalidOperationException("SOCKS4 proxy refused CONNECT", ex);
} Prevention
- Whitelist the target host:port on the proxy before deploying
- Supply the SOCKS4 userid when the proxy enforces ident checks
- Confirm the proxy speaks SOCKS4 (not SOCKS5/HTTP) before wiring it in
When it happens
Trigger: The SOCKS4 proxy refuses the CONNECT: target host/port blocked, SOCKS user-id rejected (ident check failed), proxy cannot reach the target, or wrong proxy port/protocol so the reply bytes are garbage.
Common situations: Proxy ACLs disallowing mail ports; missing or mismatched SOCKS userid when the proxy enforces ident; pointing the client at a SOCKS5-only or HTTP proxy; target host firewall dropping from the proxy's network.
Understand the failure class
Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.
Related errors
- Failed to connect to
- Could not resolve a suitable IPv4 address for
- The specified host address must be IPv4.
- Specified argument was out of the range of valid values…
- The ImapClient is not connected.
AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15).
Data as JSON: /api/errors/60b8a0bf4bbb5cf5.
Report an issue: GitHub.
Appendix: source
Thrown at MailKit/Net/Proxy/Socks4Client.cs:268
try {
var buffer = GetConnectCommand (domain, addr, port);
Send (socket, buffer, 0, buffer.Length, cancellationToken);
// +-----+-----+----------+----------+
// | VER | REP | BND.PORT | BND.ADDR |
// +-----+-----+----------+----------+
// | 1 | 1 | 2 | 4 |
// +-----+-----+----------+----------+
int nread, n = 0;
do {
if ((nread = Receive (socket, buffer, 0 + n, 8 - n, cancellationToken)) > 0)
n += nread;
} while (n < 8);
if (buffer[1] != (byte) Socks4Reply.RequestGranted)
throw new ProxyProtocolException (string.Format (CultureInfo.InvariantCulture, "Failed to connect to {0}:{1}: {2}", host, port, GetFailureReason (buffer[1])));
// TODO: do we care about BND.ADDR and BND.PORT?
return new NetworkStream (socket, true);
} catch {
if (socket.Connected)
socket.Disconnect (false);
socket.Dispose ();
throw;
}
}
/// <summary>
/// Asynchronously connect to the target host.
/// </summary>
/// <remarks>
/// Asynchronously connects to the target host and port through the proxy server.View on GitHub (pinned to 9d3859a785)