jstedfast/MailKit · error · ProxyProtocolException

Failed to connect to

Error message

Failed to connect to {0}:{1}: {2}

What it means

HttpProxyClient.Connect sends CONNECT host:port HTTP/1.1 to the proxy; ValidateHttpResponse requires an 'HTTP/1.0 200' or 'HTTP/1.1 200' status line. Any other status (403/407/502/503 or a non-HTTP reply) throws ProxyProtocolException with 'Failed to connect to host:port: <full response>'.

Solutions

  1. Read the response text in the exception message — it contains the proxy's status line and reason.
  2. For 407, supply proxy credentials (the HttpProxyClient constructor overload that accepts ICredentials).
  3. Confirm the proxy allows CONNECT to the target host:port (ask the network team / check ACLs).
  4. Verify you are using HttpProxyClient with an HTTP proxy address, not a SOCKS proxy or the mail server.
  5. Try the target connection outside the proxy to confirm the proxy, not the mail server, is the failure point.

Example fix

// before
var proxy = new HttpProxyClient("proxy.corp", 3128);
client.Connect(new IPEndPoint(proxyAddress...), ...); // 407 without credentials
// after
var proxy = new HttpProxyClient("proxy.corp", 3128, new NetworkCredential("user", "pass"));
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: does the proxy allow CONNECT?
// curl -x http://proxy:3128 -I https://target:995  (expect HTTP 200)

Try / catch

try {
    client.Connect(target, cancellationToken);
} catch (ProxyProtocolException ex) when (ex.Message.Contains("Failed to connect to")) {
    // inspect status in message: 407 -> add credentials, 403/502 -> proxy ACL/target issue
}

Prevention

When it happens

Trigger: Connecting through an HTTP proxy where the CONNECT request is denied: proxy requires authentication (407), blocks the target (403), cannot reach the target (502/503), or the endpoint is not actually an HTTP proxy (greeting is not an HTTP status line).

Common situations: Corporate proxy requiring credentials not supplied to the ProxyClient; proxy ACLs blocking non-standard ports like 587/995; pointing the client at a SOCKS proxy or the target server directly by mistake; proxy denying outbound traffic to the mail host.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


AI-assisted analysis of jstedfast/MailKit@9d3859a785 (2026-09-15). Data as JSON: /api/errors/1eec58e569579833. Report an issue: GitHub.

Appendix: source

Thrown at MailKit/Net/Proxy/HttpProxyClient.cs:141

				break;
			}

			builder.Append (c);

			return endOfHeaders;
		}

		internal static void ValidateHttpResponse (string response, string host, int port)
		{
			// Verify that the response starts with something like "HTTP/1.1 200 ..."
			if (response.Length >= 15 && response.StartsWith ("HTTP/1.", StringComparison.OrdinalIgnoreCase) &&
				(response[7] == '1' || response[7] == '0') && response[8] == ' ' &&
				response[9] == '2' && response[10] == '0' && response[11] == '0' &&
				response[12] == ' ') {
				return;
			}

			throw new ProxyProtocolException (string.Format (CultureInfo.InvariantCulture, "Failed to connect to {0}:{1}: {2}", host, port, response));
		}

		/// <summary>
		/// Connect to the target host.
		/// </summary>
		/// <remarks>
		/// Connects to the target host and port through the proxy server.
		/// </remarks>
		/// <returns>The connected network stream.</returns>
		/// <param name="host">The host name of the target server.</param>
		/// <param name="port">The target server port.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <exception cref="System.ArgumentNullException">
		/// <paramref name="host"/> is <see langword="null" />.
		/// </exception>
		/// <exception cref="System.ArgumentOutOfRangeException">
		/// <paramref name="port"/> is not between <c>0</c> and <c>65535</c>.
		/// </exception>

View on GitHub (pinned to 9d3859a785)