> For the complete documentation index, see [llms.txt](https://docs.helodata.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.helodata.com/troubleshooting/ssl-errors.md).

# SSL / TLS errors

helodata is a **forwarding** proxy — for HTTPS targets, the gateway tunnels a TCP connection via `CONNECT`, and your client negotiates TLS end-to-end with the target. So SSL errors are almost always one of:

1. Your client's CA bundle is stale
2. The target site has a broken TLS config
3. You're trying to intercept TLS yourself with another MITM tool in the chain

## Symptom: `SSL: CERTIFICATE_VERIFY_FAILED` (Python)

```
requests.exceptions.SSLError: HTTPSConnectionPool(host='example.com', port=443):
  Max retries exceeded with url: / (Caused by SSLError(SSLCertVerificationError(...)))
```

**Diagnose**

```bash
# Bypass helodata to isolate the target
openssl s_client -connect example.com:443 -servername example.com < /dev/null

# Then with helodata
curl -v --proxy http://USER:PASS@gate.helodata.io:7777 https://example.com
```

If both fail with the same cert error, **the target itself is misconfigured**.

**Fix options**

* **Update certifi** (Python): `pip install -U certifi`
* **Update CA bundle** (system): `apt update && apt install ca-certificates -y && update-ca-certificates`
* **Disable verification** as last resort — only on a test target:

  ```python
  requests.get(url, verify=False)
  ```

## Symptom: gateway returns `502` + `upstream-tls-error`

```
HTTP/1.1 502
X-Helodata-Error-Code: upstream-tls-error
```

The target's TLS handshake failed against the helodata exit IP. Most often the target:

* Has an expired certificate
* Doesn't include the intermediate certificate in its chain
* Requires a specific TLS version or cipher your exit IP's TLS stack negotiates differently from your local one

The exit IP doesn't actually matter for TLS terms — TLS is end-to-end. The gateway just observed that the handshake didn't complete in the configured time and reported it back.

**Fix**

* Retry with a fresh exit IP (rotate the session)
* If consistent across IPs, the target is broken — confirm with `openssl s_client`

## Symptom: HTTPS works at home, fails via proxy

Most common cause: **DNS resolution**. The local resolver returned an IP for a CDN closest to your home, but the proxy's resolution returned a different (sometimes misconfigured) edge.

**Fix**

* Switch to SOCKS5 with `socks5h://` so the proxy resolves DNS uniformly across your fleet.
* For very few targets, hard-code a known-good DNS over HTTPS (DoH) — but this defeats geo-targeting.

## Symptom: header `X-Helodata-Bypass-TLS-Validation: skipped`

helodata never modifies upstream TLS. If you see hints of certificate mangling in your client's logs, look for **another** MITM proxy in the chain — your corporate firewall, a debug tool like Charles or mitmproxy you forgot to disable, or a VPN client that re-signs certs.

## Self-signed targets

helodata cannot help — it doesn't re-issue certs. Your client must trust the self-signed root explicitly (`requests.get(..., verify="my-ca.pem")`).

## Quick checklist

* [ ] Did this work directly (no proxy) just now?
* [ ] Is `certifi` (Python) or your OS CA bundle up to date?
* [ ] Does `openssl s_client` succeed?
* [ ] Is there another MITM proxy (Charles, mitmproxy, corp firewall) in the chain?
* [ ] Does retrying with a different exit IP help?

If you've answered yes to "still failing" after all of these, open a ticket with `X-Helodata-Request-Id` and the `openssl s_client` output.
