# SSL WRONG_VERSION_NUMBER via a proxy: the fix

> [SSL: WRONG_VERSION_NUMBER] through a proxy usually means an https:// proxy URL on a plain HTTP proxy port. The one-line fix for Python and Node.

- URL: https://crawlrelay.com/docs/errors/ssl-wrong-version-number/
- Last updated: 2026-10-13
- Publisher: CrawlRelay (https://crawlrelay.com)

TLS error in the client: the exact message in each tool, the likely causes in order, and the fix that works.

**Quick answer — What does SSL: WRONG_VERSION_NUMBER mean with a proxy?**

**[SSL: WRONG_VERSION_NUMBER]** through a proxy almost always means your client started a TLS handshake with something that answered in plain text. The usual cause is an `https://` proxy URL pointing at a plain HTTP proxy port. With CrawlRelay, write `http://` in front of the gateway address for both HTTP and HTTPS targets; the site's own HTTPS still works through the tunnel.

## SSL: WRONG_VERSION_NUMBER at a glance

| Attribute | Value |
| --- | --- |
| Error | SSL: WRONG_VERSION_NUMBER |
| Type | TLS error in the client |
| Sent by | Your TLS library, when the other side does not speak TLS |
| Defined in | TLS 1.3: RFC 8446; HTTP proxy CONNECT: RFC 9110, section 9.3.6 |
| Retry it? | No. It is a configuration error |
| First check | Look at the scheme in front of your proxy URL |

## What does SSL: WRONG_VERSION_NUMBER mean?

TLS starts with a handshake record. If the bytes that come back are an HTTP response instead, the TLS library reads a nonsense version number and stops. Python reports `WRONG_VERSION_NUMBER`; the exact wording varies with the OpenSSL version and the client.

The proxy URL scheme decides how your client talks to the proxy. `http://` means plain HTTP to the proxy, followed by a `CONNECT` tunnel and TLS with the website. `https://` means TLS with the proxy itself, which only works if the proxy port expects TLS.

## What does SSL: WRONG_VERSION_NUMBER look like in Python, curl, Node.js and browsers?

The same failure prints differently in every tool. These are the messages to search your logs for:

- **Python requests / urllib3 2.x:** `SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number'))` wrapped in a `ProxyError`
- **httpx:** `httpx.ConnectError: [SSL: WRONG_VERSION_NUMBER] wrong version number`
- **curl:** `curl: (35) ... wrong version number` when you write `-x https://` for a plain proxy
- **Node.js:** `EPROTO ... wrong version number` in the error message

## What causes SSL: WRONG_VERSION_NUMBER?

Most likely first:

- **`https://` in front of the proxy address** on a port that speaks plain HTTP. This is the most common case.
- **Copy-pasted settings** from a provider whose proxy port does expect TLS.
- **`https://` on a URL with port 80**, or `http://` on a site port that expects TLS, outside any proxy.
- **An environment variable** such as `HTTPS_PROXY=https://...` that your code inherits.

## How do I diagnose SSL: WRONG_VERSION_NUMBER step by step?

1. Print the proxy URL your code uses and check its scheme.
2. Check the environment for `HTTPS_PROXY` and `ALL_PROXY`.
3. Run the curl test below with `-x http://` and confirm it works.
4. If curl works and your code does not, your code or environment still uses `https://`.

*Test the failing URL with curl (HTTP port, verbose)*

```bash
# Use the URL that fails; with https://api.ipify.org instead, you test the gateway alone.
# "HTTP/1.1 200 Connection established" first, then the site's own status: the site answered.
curl -v -x http://USERNAME:PASSWORD@gw.crawlrelay.com:7777 https://TARGET_URL

# Same test through the SOCKS5 port, with DNS resolved at the exit
curl -v --socks5-hostname gw.crawlrelay.com:7778 --proxy-user USERNAME:PASSWORD https://TARGET_URL
```

## How do I fix SSL: WRONG_VERSION_NUMBER?

- **Use `http://` for the proxy URL** in every key: `{"http": "http://...", "https": "http://..."}`.
- **Leave TLS verification on.** The fix is the scheme, not `verify=False`.
- **Fix the environment variable** instead of overriding it in one script.

## Should I retry after SSL: WRONG_VERSION_NUMBER?

Never retry this error: every attempt fails the same way. It is a one-character configuration fix.

## How does SSL: WRONG_VERSION_NUMBER apply to CrawlRelay?

CrawlRelay's HTTP port is a plain HTTP proxy port that carries HTTPS sites through `CONNECT` tunnels. TLS runs end to end between your client and the website inside the tunnel, so the gateway never needs an `https://` proxy URL.

Gateway: `gw.crawlrelay.com`, port 7777 (HTTP, HTTPS through CONNECT) and port 7778 (SOCKS5). Username format: `USERNAME-country-{cc}-state-{state}-city-{city}-zip-{zip}-asn-{asn}-session-{id}-ttl-{minutes}`. Related: [SSL certificate verify failed](https://crawlrelay.com/docs/errors/ssl-certificate-verify-failed/) · [Cannot connect to proxy](https://crawlrelay.com/docs/errors/cannot-connect-to-proxy/) · [Python guide](https://crawlrelay.com/docs/python/).

## SSL: WRONG_VERSION_NUMBER: questions developers ask

### Is my traffic unencrypted if I use an http:// proxy URL?

Not for HTTPS websites. The `http://` scheme only covers the short CONNECT exchange with the proxy, which includes your proxy credentials. After that, your client runs TLS directly with the website inside the tunnel, and the proxy only forwards encrypted bytes. Plain `http://` websites are unencrypted with or without a proxy.

### Why did this start after upgrading urllib3?

urllib3 2.x supports HTTPS proxies, so it takes an `https://` proxy URL literally and starts TLS with the proxy. Older setups sometimes worked by accident with the wrong scheme. Write `http://` for plain HTTP proxy ports and the error goes away.

### Should I set verify=False to make the error go away?

No. Turning off certificate checks does not fix a wrong scheme, and it exposes you to interception on every request. Fix the proxy URL scheme. Keep verification on in production.

## Other proxy errors in this reference

- [401 Unauthorized vs 407](https://crawlrelay.com/docs/errors/401-unauthorized/)
- [403 Forbidden](https://crawlrelay.com/docs/errors/403-forbidden/)
- [407 Proxy Authentication Required](https://crawlrelay.com/docs/errors/407-proxy-authentication-required/)
- [429 Too Many Requests](https://crawlrelay.com/docs/errors/429-too-many-requests/)
- [502 Bad Gateway](https://crawlrelay.com/docs/errors/502-bad-gateway/)
- [503 Service Unavailable](https://crawlrelay.com/docs/errors/503-service-unavailable/)
- [504 Gateway Timeout](https://crawlrelay.com/docs/errors/504-gateway-timeout/)
- [Cannot connect to proxy (ProxyError)](https://crawlrelay.com/docs/errors/cannot-connect-to-proxy/)
- [Connection reset by peer (ECONNRESET)](https://crawlrelay.com/docs/errors/connection-reset/)
- [ERR_PROXY_CONNECTION_FAILED](https://crawlrelay.com/docs/errors/err-proxy-connection-failed/)
- [ERR_TUNNEL_CONNECTION_FAILED](https://crawlrelay.com/docs/errors/err-tunnel-connection-failed/)
- [Read timed out (ReadTimeout)](https://crawlrelay.com/docs/errors/read-timeout/)
- [SOCKS5 proxy errors](https://crawlrelay.com/docs/errors/socks5-proxy-errors/)
- [SSL: CERTIFICATE_VERIFY_FAILED](https://crawlrelay.com/docs/errors/ssl-certificate-verify-failed/)
- [SSL: WRONG_VERSION_NUMBER](https://crawlrelay.com/docs/errors/ssl-wrong-version-number/)

**Residential proxies with docs that cover the failure cases** CrawlRelay residential proxies from $0.50/GB, traffic that never expires. [See pricing](https://crawlrelay.com/pricing/) · [Quick start](https://crawlrelay.com/docs/)

---

CrawlRelay: CrawlRelay is a developer-first rotating residential and 4G/5G mobile proxy service for scrapers and AI data pipelines: non-expiring pay-as-you-go traffic from $0.50/GB, paid in crypto, with no ID upload. No KYC — no ID, no selfie, no documents. Pay in crypto.
