# Results: case by Axios version

Recorded on 11 November 2026 on macOS 26.5.1 arm64 with Node.js v24.22.2 and v26.13.0. A cell holds the
result on both Node versions; where they differ, both are given. The full records are in results.json.

## Main versions


### a. `proxy` config

| Case | 1.12.2 | 1.19.0 | 1.20.0 | 1.21.0 | 1.21.1 |
| --- | --- | --- | --- | --- | --- |
| no proxy anywhere (baseline) (`a-direct-baseline`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| proxy: { protocol, host, port }, https:// URL (`a-proxy-config`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| proxy: { host, port } without protocol (`a-proxy-config-no-protocol`) | `EPROTO` wrong version number | through proxy | through proxy | through proxy | through proxy |
| proxy config, http:// URL (`a-proxy-config-http-url`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| proxy.host: 'http://127.0.0.1' (scheme inside host) (`a-proxy-host-with-scheme`) | `ENOTFOUND` getaddrinfo ENOTFOUND http://127.0.0.1 | `ERR_INVALID_URL` Invalid URL | `ERR_INVALID_URL` Invalid URL | `ERR_INVALID_URL` Invalid URL | `ERR_INVALID_URL` Invalid URL |
| proxy: 'http://127.0.0.1:PORT' (a string, not an object) (`a-proxy-string`) | `ECONNREFUSED` connect ECONNREFUSED ::1:443 | `ENOTFOUND` getaddrinfo ENOTFOUND undefined | `ENOTFOUND` getaddrinfo ENOTFOUND undefined | `ENOTFOUND` getaddrinfo ENOTFOUND undefined | `ENOTFOUND` getaddrinfo ENOTFOUND undefined |
| proxy.protocol: 'https' for a plain HTTP proxy (`a-proxy-protocol-https`) | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number |
| proxy.port as a string (`a-proxy-port-string`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| axios.create({ proxy }) instance default (`a-proxy-in-create`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| proxy: false with HTTPS_PROXY set (`a-proxy-false`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| proxy config (D) with HTTPS_PROXY (A) and matching NO_PROXY (`a-config-beats-env`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |

### b. Authentication

| Case | 1.12.2 | 1.19.0 | 1.20.0 | 1.21.0 | 1.21.1 |
| --- | --- | --- | --- | --- | --- |
| proxy.auth, correct password (`b-auth-ok`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| proxy.auth, wrong password (`b-auth-wrong`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| no credentials, proxy requires them (`b-auth-missing`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| credentials in top-level auth instead of proxy.auth (`b-auth-top-level`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| proxy.auth, wrong password, http:// URL (`b-auth-wrong-http-url`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| proxy.auth, correct password, http:// URL (`b-auth-ok-http-url`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| proxy.auth with password p@ss/w0rd#1 (`b-auth-special-object`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| proxy.auth with the password percent-encoded (`b-auth-special-object-encoded`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| HTTPS_PROXY with user:pass@ (`b-auth-env-ok`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| HTTPS_PROXY with a wrong password (`b-auth-env-wrong`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| HTTPS_PROXY with p@ss/w0rd#1 pasted as is (`b-auth-env-special-raw`) | `ENOTFOUND` getaddrinfo ENOTFOUND ss | `ENOTFOUND` getaddrinfo ENOTFOUND ss | `ENOTFOUND` getaddrinfo ENOTFOUND ss | `ENOTFOUND` getaddrinfo ENOTFOUND ss | `ENOTFOUND` getaddrinfo ENOTFOUND ss |
| HTTPS_PROXY with the password percent-encoded (`b-auth-env-special-encoded`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| HttpsProxyAgent with user:pass@, proxy: false (`b-auth-agent-ok`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| HttpsProxyAgent with a wrong password, proxy: false (`b-auth-agent-wrong`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| HttpsProxyAgent, password percent-encoded in the URL (`b-auth-agent-special-encoded`) | through proxy | through proxy | through proxy | through proxy | through proxy |

### c. Environment variables

| Case | 1.12.2 | 1.19.0 | 1.20.0 | 1.21.0 | 1.21.1 |
| --- | --- | --- | --- | --- | --- |
| HTTPS_PROXY, https:// URL (`c-HTTPS_PROXY`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| https_proxy (lowercase), https:// URL (`c-https_proxy`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| only HTTP_PROXY, https:// URL (`c-HTTP_PROXY-only`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| only http_proxy (lowercase), https:// URL (`c-http_proxy-only`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| HTTP_PROXY, http:// URL (`c-HTTP_PROXY-http-url`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| http_proxy (lowercase), http:// URL (`c-http_proxy-http-url`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| only HTTPS_PROXY, http:// URL (`c-HTTPS_PROXY-http-url`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| only ALL_PROXY (`c-ALL_PROXY`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| only all_proxy (lowercase) (`c-all_proxy`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| HTTPS_PROXY (A) and https_proxy (D) both set (`c-upper-vs-lower`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| HTTPS_PROXY=127.0.0.1:PORT (no scheme) (`c-env-no-scheme`) | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number |
| HTTPS_PROXY=https://127.0.0.1:PORT for a plain HTTP proxy (`c-env-https-scheme`) | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number |
| process.env.HTTPS_PROXY assigned in code before the request (`c-env-set-in-code`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| HTTPS_PROXY plus a plain httpsAgent (keepAlive) (`c-env-with-plain-agent`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |

### d. NO_PROXY (HTTPS_PROXY or HTTP_PROXY set)

| Case | 1.12.2 | 1.19.0 | 1.20.0 | 1.21.0 | 1.21.1 |
| --- | --- | --- | --- | --- | --- |
| NO_PROXY=target.test (`d-exact`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| no_proxy=target.test (lowercase) (`d-lowercase-var`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=TARGET.TEST (`d-uppercase-host`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=.test (`d-leading-dot`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=.target.test (`d-leading-dot-full`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| NO_PROXY=*.test (`d-wildcard`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=* (`d-star`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=other.test,* (`d-star-in-list`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=test (`d-bare-suffix`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| NO_PROXY=get.test (tail of target.test) (`d-partial-suffix`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| NO_PROXY=other.test (`d-other-host`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| NO_PROXY=target.test:PORT (`d-port-match`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=target.test:9999 (`d-port-mismatch`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| NO_PROXY="other.test target.test" (spaces) (`d-space-list`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY="other.test, target.test" (`d-comma-space-list`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=https://target.test (`d-with-scheme`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| URL host target.test. with NO_PROXY=target.test (http) (`d-trailing-dot-url`) | through proxy | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| URL 127.0.0.1 with NO_PROXY=127.0.0.1 (http) (`d-ip-exact`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| URL 127.0.0.1 with NO_PROXY=127.0.0.0/8 (http) (`d-cidr`) | through proxy | through proxy | bypassed silently | bypassed silently | bypassed silently |
| URL 127.0.0.1, HTTP_PROXY set, NO_PROXY unset (http) (`d-loopback-unset`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| URL localhost, HTTP_PROXY set, NO_PROXY unset (http) (`d-localhost-unset`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| URL 127.0.0.1 with NO_PROXY=localhost (http) (`d-localhost-vs-ip`) | through proxy | bypassed silently | bypassed silently | bypassed silently | bypassed silently |

### e. Proxy agents

| Case | 1.12.2 | 1.19.0 | 1.20.0 | 1.21.0 | 1.21.1 |
| --- | --- | --- | --- | --- | --- |
| proxy: false + httpsAgent: new HttpsProxyAgent() (`e-agent-proxy-false`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| the same with HTTPS_PROXY (D) also set (`e-agent-proxy-false-env`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| httpsAgent: new HttpsProxyAgent(), no proxy option, no env (`e-agent-only`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| HttpsProxyAgent (A) without proxy: false, HTTPS_PROXY (D) set (`e-agent-plus-env`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| HttpsProxyAgent (A) plus proxy config (D) (`e-agent-plus-config`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| HttpsProxyAgent passed as httpAgent only, https:// URL (`e-agent-in-httpAgent`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| HttpProxyAgent passed as httpsAgent, https:// URL (`e-http-agent-as-https`) | `502` (ERR_BAD_RESPONSE) | `502` (ERR_BAD_RESPONSE) | `502` (ERR_BAD_RESPONSE) | `502` (ERR_BAD_RESPONSE) | `502` (ERR_BAD_RESPONSE) |
| HttpsProxyAgent('https://…') for a plain HTTP proxy (`e-agent-https-scheme`) | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number |
| HttpProxyAgent as httpAgent, http:// URL, proxy: false (`e-both-agents-http-url`) | through proxy | through proxy | through proxy | through proxy | through proxy |

### f. `proxy: false` + `https.Agent({ proxyEnv })`

| Case | 1.12.2 | 1.19.0 | 1.20.0 | 1.21.0 | 1.21.1 |
| --- | --- | --- | --- | --- | --- |
| proxy: false + https.Agent({ proxyEnv }) (`f-proxyenv-proxy-false`) | through proxy | through proxy | through proxy | bypassed silently | bypassed silently |

### g. Node's own proxy support

| Case | 1.12.2 | 1.19.0 | 1.20.0 | 1.21.0 | 1.21.1 |
| --- | --- | --- | --- | --- | --- |
| https.Agent({ proxyEnv }), no proxy option (`g-proxyenv`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| https.Agent({ proxyEnv: A }) with HTTPS_PROXY (D) also set (`g-proxyenv-plus-env`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| NODE_USE_ENV_PROXY=1 + HTTPS_PROXY, plain axios.get (`g-node-env-proxy`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| NODE_USE_ENV_PROXY=1 + HTTPS_PROXY, proxy: false (`g-node-env-proxy-proxy-false`) | through proxy | through proxy | through proxy | bypassed silently | bypassed silently |
| --use-env-proxy + HTTPS_PROXY, proxy: false (`g-use-env-proxy-flag-proxy-false`) | through proxy | through proxy | through proxy | bypassed silently | bypassed silently |

### h. HTTP/2 (`httpVersion: 2`)

| Case | 1.12.2 | 1.19.0 | 1.20.0 | 1.21.0 | 1.21.1 |
| --- | --- | --- | --- | --- | --- |
| httpVersion: 2, no proxy (baseline) (`h-h2-direct`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| httpVersion: 2 + proxy config (`h-h2-proxy-config`) | `400` (ERR_BAD_REQUEST) | bypassed silently | `ERR_NOT_SUPPORT` HTTP/2 requests with a proxy are not supported | `ERR_NOT_SUPPORT` HTTP/2 requests with a proxy are not supported | `ERR_NOT_SUPPORT` HTTP/2 requests with a proxy are not supported |
| httpVersion: 2 + HTTPS_PROXY (`h-h2-env`) | `400` (ERR_BAD_REQUEST) | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| httpVersion: 2 + proxy: false + HttpsProxyAgent (`h-h2-agent`) | through proxy | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| axios.create({ httpVersion: 2, proxy }) (`h-h2-create`) | `400` (ERR_BAD_REQUEST) | bypassed silently | `ERR_NOT_SUPPORT` HTTP/2 requests with a proxy are not supported | `ERR_NOT_SUPPORT` HTTP/2 requests with a proxy are not supported | `ERR_NOT_SUPPORT` HTTP/2 requests with a proxy are not supported |
| httpVersion: 2 + NODE_USE_ENV_PROXY=1 + HTTPS_PROXY (`h-h2-node-env-proxy`) | `400` (ERR_BAD_REQUEST) | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| no httpVersion (HTTP/1.1) + HTTPS_PROXY, same target (`h-h1-default-env`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |

### i. Redirects

| Case | 1.12.2 | 1.19.0 | 1.20.0 | 1.21.0 | 1.21.1 |
| --- | --- | --- | --- | --- | --- |
| proxy config, https → https redirect to another host (`i-redirect-config`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| HTTPS_PROXY, https → https redirect to another host (`i-redirect-env`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| HTTPS_PROXY + NO_PROXY=other.test, redirect to other.test (`i-redirect-env-no-proxy`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | partly bypassed | partly bypassed |
| proxy config + NO_PROXY=other.test, redirect to other.test (`i-redirect-config-no-proxy`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| proxy: false + HttpsProxyAgent, redirect to another host (`i-redirect-agent`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| proxy config with auth, redirect to another host (`i-redirect-auth`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| only HTTP_PROXY, http:// URL redirects to https:// (`i-redirect-http-to-https-env`) | partly bypassed | partly bypassed | partly bypassed | partly bypassed | partly bypassed |
| HTTP_PROXY + HTTPS_PROXY, http:// URL redirects to https:// (`i-redirect-http-to-https-both-env`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| proxy config, http:// URL redirects to https:// (`i-redirect-http-to-https-config`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| proxy: false + HttpProxyAgent as httpAgent only, http → https redirect (`i-redirect-http-to-https-agent`) | partly bypassed | partly bypassed | partly bypassed | partly bypassed | partly bypassed |
| proxy: false + httpAgent and httpsAgent, http → https redirect (`i-redirect-http-to-https-both-agents`) | through proxy | through proxy | through proxy | through proxy | through proxy |

### j. Fetch adapter

| Case | 1.12.2 | 1.19.0 | 1.20.0 | 1.21.0 | 1.21.1 |
| --- | --- | --- | --- | --- | --- |
| adapter: 'fetch' + proxy config (`j-fetch-proxy-config`) | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently |
| adapter: 'fetch' + HTTPS_PROXY (`j-fetch-env`) | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently |
| adapter: 'fetch' + httpsAgent: new HttpsProxyAgent() (`j-fetch-agent`) | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently |
| adapter: 'fetch' + NODE_USE_ENV_PROXY=1 + HTTPS_PROXY (`j-fetch-node-env-proxy`) | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy |
| adapter: 'fetch' + NODE_USE_ENV_PROXY=1 + HTTPS_PROXY, proxy: false (`j-fetch-node-env-proxy-proxy-false`) | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy |

### k. SOCKS5

| Case | 1.12.2 | 1.19.0 | 1.20.0 | 1.21.0 | 1.21.1 |
| --- | --- | --- | --- | --- | --- |
| proxy: false + SocksProxyAgent('socks5://…') (`k-socks5`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| proxy: false + SocksProxyAgent('socks5h://…') (`k-socks5h`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| socks5://, a name only the proxy can resolve (`k-socks5-proxy-only-name`) | `ENOTFOUND` getaddrinfo ENOTFOUND proxy-only.test | `ENOTFOUND` getaddrinfo ENOTFOUND proxy-only.test | `ENOTFOUND` getaddrinfo ENOTFOUND proxy-only.test | `ENOTFOUND` getaddrinfo ENOTFOUND proxy-only.test | `ENOTFOUND` getaddrinfo ENOTFOUND proxy-only.test |
| socks5h://, a name only the proxy can resolve (`k-socks5h-proxy-only-name`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| socks5h:// with user:pass@, correct (`k-socks-auth-ok`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| socks5h:// with a wrong password (`k-socks-auth-wrong`) | Socks5 Authentication failed | Socks5 Authentication failed | Socks5 Authentication failed | Socks5 Authentication failed | Socks5 Authentication failed |
| SocksProxyAgent without proxy: false, no env (`k-socks-no-proxy-false`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| SocksProxyAgent without proxy: false, HTTPS_PROXY (A) set (`k-socks-plus-env`) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy | through proxy | through proxy |
| proxy: { protocol: 'socks5', host, port } (`k-socks-in-proxy-config`) | `ERR_ASSERTION` protocol mismatch | never settled | never settled | never settled | never settled |
| HTTPS_PROXY=socks5://127.0.0.1:PORT (`k-socks-in-env`) | `ERR_ASSERTION` protocol mismatch | never settled | never settled | never settled | never settled |
| SocksProxyAgent as httpAgent, http:// URL, proxy: false (`k-socks-http-url`) | through proxy | through proxy | through proxy | through proxy | through proxy |

### l. A proxy that is down or does not answer

| Case | 1.12.2 | 1.19.0 | 1.20.0 | 1.21.0 | 1.21.1 |
| --- | --- | --- | --- | --- | --- |
| proxy config, nothing listens on the proxy port (`l-refused-config`) | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT |
| proxy: false + HttpsProxyAgent, nothing listens on the proxy port (`l-refused-agent`) | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT |
| proxy config, proxy closes the connection after CONNECT (`l-close-config`) | `ECONNRESET` socket hang up | never settled | never settled | never settled | never settled |
| HTTPS_PROXY, proxy closes the connection after CONNECT (`l-close-env`) | `ECONNRESET` socket hang up | never settled | never settled | never settled | never settled |
| proxy: false + HttpsProxyAgent, proxy closes the connection (`l-close-agent`) | Proxy connection ended before receiving CONNECT response | Proxy connection ended before receiving CONNECT response | Proxy connection ended before receiving CONNECT response | Proxy connection ended before receiving CONNECT response | Proxy connection ended before receiving CONNECT response |
| proxy config, http:// URL, proxy closes the connection (`l-close-config-http-url`) | `ECONNRESET` socket hang up | `ECONNRESET` socket hang up | `ECONNRESET` socket hang up | `ECONNRESET` socket hang up | `ECONNRESET` socket hang up |
| proxy config, proxy never answers CONNECT (`l-silent-config`) | `ECONNABORTED` timeout of 5000ms exceeded | never settled | never settled | never settled | never settled |
| the same with signal: AbortSignal.timeout(3000) (`l-silent-config-signal`) | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled |
| proxy closes the connection, signal: AbortSignal.timeout(3000) (`l-close-config-signal`) | `ECONNRESET` socket hang up | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled |
| proxy: false + HttpsProxyAgent, proxy never answers CONNECT (`l-silent-agent`) | never settled | never settled | never settled | never settled | never settled |
| the same with signal: AbortSignal.timeout(3000) (`l-silent-agent-signal`) | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled |
| proxy config, http:// URL, proxy never answers (`l-silent-config-http-url`) | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded |
| proxy never answers CONNECT, maxRedirects: 0 (`l-silent-config-no-redirects`) | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded |

## Sweep versions (to find where behaviour changed)


### a. `proxy` config

| Case | 1.13.6 | 1.15.0 | 1.16.0 | 1.16.1 | 1.18.1 |
| --- | --- | --- | --- | --- | --- |
| no proxy anywhere (baseline) (`a-direct-baseline`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| proxy: { protocol, host, port }, https:// URL (`a-proxy-config`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| proxy: { host, port } without protocol (`a-proxy-config-no-protocol`) | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | through proxy | through proxy |
| proxy config, http:// URL (`a-proxy-config-http-url`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| proxy.host: 'http://127.0.0.1' (scheme inside host) (`a-proxy-host-with-scheme`) | `ENOTFOUND` getaddrinfo ENOTFOUND http://127.0.0.1 | `ENOTFOUND` getaddrinfo ENOTFOUND http://127.0.0.1 | `ENOTFOUND` getaddrinfo ENOTFOUND http://127.0.0.1 | `ERR_INVALID_URL` Invalid URL | `ERR_INVALID_URL` Invalid URL |
| proxy: 'http://127.0.0.1:PORT' (a string, not an object) (`a-proxy-string`) | `ECONNREFUSED` connect ECONNREFUSED ::1:443 | `ECONNREFUSED` connect ECONNREFUSED ::1:443 | `ECONNREFUSED` connect ECONNREFUSED ::1:443 | `ENOTFOUND` getaddrinfo ENOTFOUND undefined | `ENOTFOUND` getaddrinfo ENOTFOUND undefined |
| proxy.protocol: 'https' for a plain HTTP proxy (`a-proxy-protocol-https`) | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number |
| proxy.port as a string (`a-proxy-port-string`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| axios.create({ proxy }) instance default (`a-proxy-in-create`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| proxy: false with HTTPS_PROXY set (`a-proxy-false`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| proxy config (D) with HTTPS_PROXY (A) and matching NO_PROXY (`a-config-beats-env`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |

### b. Authentication

| Case | 1.13.6 | 1.15.0 | 1.16.0 | 1.16.1 | 1.18.1 |
| --- | --- | --- | --- | --- | --- |
| proxy.auth, correct password (`b-auth-ok`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| proxy.auth, wrong password (`b-auth-wrong`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| no credentials, proxy requires them (`b-auth-missing`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| credentials in top-level auth instead of proxy.auth (`b-auth-top-level`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| proxy.auth, wrong password, http:// URL (`b-auth-wrong-http-url`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| proxy.auth, correct password, http:// URL (`b-auth-ok-http-url`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| proxy.auth with password p@ss/w0rd#1 (`b-auth-special-object`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| proxy.auth with the password percent-encoded (`b-auth-special-object-encoded`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| HTTPS_PROXY with user:pass@ (`b-auth-env-ok`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| HTTPS_PROXY with a wrong password (`b-auth-env-wrong`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| HTTPS_PROXY with p@ss/w0rd#1 pasted as is (`b-auth-env-special-raw`) | `ENOTFOUND` getaddrinfo ENOTFOUND ss | `ENOTFOUND` getaddrinfo ENOTFOUND ss | `ENOTFOUND` getaddrinfo ENOTFOUND ss | `ENOTFOUND` getaddrinfo ENOTFOUND ss | `ENOTFOUND` getaddrinfo ENOTFOUND ss |
| HTTPS_PROXY with the password percent-encoded (`b-auth-env-special-encoded`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| HttpsProxyAgent with user:pass@, proxy: false (`b-auth-agent-ok`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| HttpsProxyAgent with a wrong password, proxy: false (`b-auth-agent-wrong`) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) | `407` (ERR_BAD_REQUEST) |
| HttpsProxyAgent, password percent-encoded in the URL (`b-auth-agent-special-encoded`) | through proxy | through proxy | through proxy | through proxy | through proxy |

### c. Environment variables

| Case | 1.13.6 | 1.15.0 | 1.16.0 | 1.16.1 | 1.18.1 |
| --- | --- | --- | --- | --- | --- |
| HTTPS_PROXY, https:// URL (`c-HTTPS_PROXY`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| https_proxy (lowercase), https:// URL (`c-https_proxy`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| only HTTP_PROXY, https:// URL (`c-HTTP_PROXY-only`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| only http_proxy (lowercase), https:// URL (`c-http_proxy-only`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| HTTP_PROXY, http:// URL (`c-HTTP_PROXY-http-url`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| http_proxy (lowercase), http:// URL (`c-http_proxy-http-url`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| only HTTPS_PROXY, http:// URL (`c-HTTPS_PROXY-http-url`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| only ALL_PROXY (`c-ALL_PROXY`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| only all_proxy (lowercase) (`c-all_proxy`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| HTTPS_PROXY (A) and https_proxy (D) both set (`c-upper-vs-lower`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| HTTPS_PROXY=127.0.0.1:PORT (no scheme) (`c-env-no-scheme`) | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number |
| HTTPS_PROXY=https://127.0.0.1:PORT for a plain HTTP proxy (`c-env-https-scheme`) | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number |
| process.env.HTTPS_PROXY assigned in code before the request (`c-env-set-in-code`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| HTTPS_PROXY plus a plain httpsAgent (keepAlive) (`c-env-with-plain-agent`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |

### d. NO_PROXY (HTTPS_PROXY or HTTP_PROXY set)

| Case | 1.13.6 | 1.15.0 | 1.16.0 | 1.16.1 | 1.18.1 |
| --- | --- | --- | --- | --- | --- |
| NO_PROXY=target.test (`d-exact`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| no_proxy=target.test (lowercase) (`d-lowercase-var`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=TARGET.TEST (`d-uppercase-host`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=.test (`d-leading-dot`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=.target.test (`d-leading-dot-full`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| NO_PROXY=*.test (`d-wildcard`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=* (`d-star`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=other.test,* (`d-star-in-list`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=test (`d-bare-suffix`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| NO_PROXY=get.test (tail of target.test) (`d-partial-suffix`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| NO_PROXY=other.test (`d-other-host`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| NO_PROXY=target.test:PORT (`d-port-match`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=target.test:9999 (`d-port-mismatch`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| NO_PROXY="other.test target.test" (spaces) (`d-space-list`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY="other.test, target.test" (`d-comma-space-list`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| NO_PROXY=https://target.test (`d-with-scheme`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| URL host target.test. with NO_PROXY=target.test (http) (`d-trailing-dot-url`) | through proxy | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| URL 127.0.0.1 with NO_PROXY=127.0.0.1 (http) (`d-ip-exact`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| URL 127.0.0.1 with NO_PROXY=127.0.0.0/8 (http) (`d-cidr`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| URL 127.0.0.1, HTTP_PROXY set, NO_PROXY unset (http) (`d-loopback-unset`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| URL localhost, HTTP_PROXY set, NO_PROXY unset (http) (`d-localhost-unset`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| URL 127.0.0.1 with NO_PROXY=localhost (http) (`d-localhost-vs-ip`) | through proxy | through proxy | bypassed silently | bypassed silently | bypassed silently |

### e. Proxy agents

| Case | 1.13.6 | 1.15.0 | 1.16.0 | 1.16.1 | 1.18.1 |
| --- | --- | --- | --- | --- | --- |
| proxy: false + httpsAgent: new HttpsProxyAgent() (`e-agent-proxy-false`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| the same with HTTPS_PROXY (D) also set (`e-agent-proxy-false-env`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| httpsAgent: new HttpsProxyAgent(), no proxy option, no env (`e-agent-only`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| HttpsProxyAgent (A) without proxy: false, HTTPS_PROXY (D) set (`e-agent-plus-env`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| HttpsProxyAgent (A) plus proxy config (D) (`e-agent-plus-config`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| HttpsProxyAgent passed as httpAgent only, https:// URL (`e-agent-in-httpAgent`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| HttpProxyAgent passed as httpsAgent, https:// URL (`e-http-agent-as-https`) | `502` (ERR_BAD_RESPONSE) | `502` (ERR_BAD_RESPONSE) | `502` (ERR_BAD_RESPONSE) | `502` (ERR_BAD_RESPONSE) | `502` (ERR_BAD_RESPONSE) |
| HttpsProxyAgent('https://…') for a plain HTTP proxy (`e-agent-https-scheme`) | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number | `EPROTO` wrong version number |
| HttpProxyAgent as httpAgent, http:// URL, proxy: false (`e-both-agents-http-url`) | through proxy | through proxy | through proxy | through proxy | through proxy |

### f. `proxy: false` + `https.Agent({ proxyEnv })`

| Case | 1.13.6 | 1.15.0 | 1.16.0 | 1.16.1 | 1.18.1 |
| --- | --- | --- | --- | --- | --- |
| proxy: false + https.Agent({ proxyEnv }) (`f-proxyenv-proxy-false`) | through proxy | through proxy | through proxy | through proxy | through proxy |

### g. Node's own proxy support

| Case | 1.13.6 | 1.15.0 | 1.16.0 | 1.16.1 | 1.18.1 |
| --- | --- | --- | --- | --- | --- |
| https.Agent({ proxyEnv }), no proxy option (`g-proxyenv`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| https.Agent({ proxyEnv: A }) with HTTPS_PROXY (D) also set (`g-proxyenv-plus-env`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| NODE_USE_ENV_PROXY=1 + HTTPS_PROXY, plain axios.get (`g-node-env-proxy`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| NODE_USE_ENV_PROXY=1 + HTTPS_PROXY, proxy: false (`g-node-env-proxy-proxy-false`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| --use-env-proxy + HTTPS_PROXY, proxy: false (`g-use-env-proxy-flag-proxy-false`) | through proxy | through proxy | through proxy | through proxy | through proxy |

### h. HTTP/2 (`httpVersion: 2`)

| Case | 1.13.6 | 1.15.0 | 1.16.0 | 1.16.1 | 1.18.1 |
| --- | --- | --- | --- | --- | --- |
| httpVersion: 2, no proxy (baseline) (`h-h2-direct`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| httpVersion: 2 + proxy config (`h-h2-proxy-config`) | `ERR_HTTP2_ERROR` Protocol error | `ERR_HTTP2_ERROR` Protocol error | `ERR_HTTP2_ERROR` Protocol error | bypassed silently | bypassed silently |
| httpVersion: 2 + HTTPS_PROXY (`h-h2-env`) | `ERR_HTTP2_ERROR` Protocol error | `ERR_HTTP2_ERROR` Protocol error | `ERR_HTTP2_ERROR` Protocol error | bypassed silently | bypassed silently |
| httpVersion: 2 + proxy: false + HttpsProxyAgent (`h-h2-agent`) | bypassed silently | bypassed silently | bypassed silently | bypassed silently | bypassed silently |
| axios.create({ httpVersion: 2, proxy }) (`h-h2-create`) | `ERR_HTTP2_ERROR` Protocol error | `ERR_HTTP2_ERROR` Protocol error | `ERR_HTTP2_ERROR` Protocol error | bypassed silently | bypassed silently |
| httpVersion: 2 + NODE_USE_ENV_PROXY=1 + HTTPS_PROXY (`h-h2-node-env-proxy`) | `ERR_HTTP2_ERROR` Protocol error | `ERR_HTTP2_ERROR` Protocol error | `ERR_HTTP2_ERROR` Protocol error | bypassed silently | bypassed silently |
| no httpVersion (HTTP/1.1) + HTTPS_PROXY, same target (`h-h1-default-env`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |

### i. Redirects

| Case | 1.13.6 | 1.15.0 | 1.16.0 | 1.16.1 | 1.18.1 |
| --- | --- | --- | --- | --- | --- |
| proxy config, https → https redirect to another host (`i-redirect-config`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| HTTPS_PROXY, https → https redirect to another host (`i-redirect-env`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| HTTPS_PROXY + NO_PROXY=other.test, redirect to other.test (`i-redirect-env-no-proxy`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| proxy config + NO_PROXY=other.test, redirect to other.test (`i-redirect-config-no-proxy`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| proxy: false + HttpsProxyAgent, redirect to another host (`i-redirect-agent`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| proxy config with auth, redirect to another host (`i-redirect-auth`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| only HTTP_PROXY, http:// URL redirects to https:// (`i-redirect-http-to-https-env`) | partly bypassed | partly bypassed | partly bypassed | partly bypassed | partly bypassed |
| HTTP_PROXY + HTTPS_PROXY, http:// URL redirects to https:// (`i-redirect-http-to-https-both-env`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| proxy config, http:// URL redirects to https:// (`i-redirect-http-to-https-config`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| proxy: false + HttpProxyAgent as httpAgent only, http → https redirect (`i-redirect-http-to-https-agent`) | partly bypassed | partly bypassed | partly bypassed | partly bypassed | partly bypassed |
| proxy: false + httpAgent and httpsAgent, http → https redirect (`i-redirect-http-to-https-both-agents`) | through proxy | through proxy | through proxy | through proxy | through proxy |

### j. Fetch adapter

| Case | 1.13.6 | 1.15.0 | 1.16.0 | 1.16.1 | 1.18.1 |
| --- | --- | --- | --- | --- | --- |
| adapter: 'fetch' + proxy config (`j-fetch-proxy-config`) | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently |
| adapter: 'fetch' + HTTPS_PROXY (`j-fetch-env`) | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently |
| adapter: 'fetch' + httpsAgent: new HttpsProxyAgent() (`j-fetch-agent`) | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently | Node 24: bypassed silently; Node 26: bypassed silently |
| adapter: 'fetch' + NODE_USE_ENV_PROXY=1 + HTTPS_PROXY (`j-fetch-node-env-proxy`) | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy |
| adapter: 'fetch' + NODE_USE_ENV_PROXY=1 + HTTPS_PROXY, proxy: false (`j-fetch-node-env-proxy-proxy-false`) | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy | Node 24: through proxy; Node 26: through proxy |

### k. SOCKS5

| Case | 1.13.6 | 1.15.0 | 1.16.0 | 1.16.1 | 1.18.1 |
| --- | --- | --- | --- | --- | --- |
| proxy: false + SocksProxyAgent('socks5://…') (`k-socks5`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| proxy: false + SocksProxyAgent('socks5h://…') (`k-socks5h`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| socks5://, a name only the proxy can resolve (`k-socks5-proxy-only-name`) | `ENOTFOUND` getaddrinfo ENOTFOUND proxy-only.test | `ENOTFOUND` getaddrinfo ENOTFOUND proxy-only.test | `ENOTFOUND` getaddrinfo ENOTFOUND proxy-only.test | `ENOTFOUND` getaddrinfo ENOTFOUND proxy-only.test | `ENOTFOUND` getaddrinfo ENOTFOUND proxy-only.test |
| socks5h://, a name only the proxy can resolve (`k-socks5h-proxy-only-name`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| socks5h:// with user:pass@, correct (`k-socks-auth-ok`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| socks5h:// with a wrong password (`k-socks-auth-wrong`) | Socks5 Authentication failed | Socks5 Authentication failed | Socks5 Authentication failed | Socks5 Authentication failed | Socks5 Authentication failed |
| SocksProxyAgent without proxy: false, no env (`k-socks-no-proxy-false`) | through proxy | through proxy | through proxy | through proxy | through proxy |
| SocksProxyAgent without proxy: false, HTTPS_PROXY (A) set (`k-socks-plus-env`) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | `400` (ERR_BAD_REQUEST) | through proxy | through proxy |
| proxy: { protocol: 'socks5', host, port } (`k-socks-in-proxy-config`) | `ERR_ASSERTION` protocol mismatch | `ERR_ASSERTION` protocol mismatch | `ERR_ASSERTION` protocol mismatch | never settled | never settled |
| HTTPS_PROXY=socks5://127.0.0.1:PORT (`k-socks-in-env`) | `ERR_ASSERTION` protocol mismatch | `ERR_ASSERTION` protocol mismatch | `ERR_ASSERTION` protocol mismatch | never settled | never settled |
| SocksProxyAgent as httpAgent, http:// URL, proxy: false (`k-socks-http-url`) | through proxy | through proxy | through proxy | through proxy | through proxy |

### l. A proxy that is down or does not answer

| Case | 1.13.6 | 1.15.0 | 1.16.0 | 1.16.1 | 1.18.1 |
| --- | --- | --- | --- | --- | --- |
| proxy config, nothing listens on the proxy port (`l-refused-config`) | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT |
| proxy: false + HttpsProxyAgent, nothing listens on the proxy port (`l-refused-agent`) | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT | `ECONNREFUSED` connect ECONNREFUSED 127.0.0.1:PORT |
| proxy config, proxy closes the connection after CONNECT (`l-close-config`) | `ECONNRESET` socket hang up | `ECONNRESET` socket hang up | `ECONNRESET` socket hang up | never settled | never settled |
| HTTPS_PROXY, proxy closes the connection after CONNECT (`l-close-env`) | `ECONNRESET` socket hang up | `ECONNRESET` socket hang up | `ECONNRESET` socket hang up | never settled | never settled |
| proxy: false + HttpsProxyAgent, proxy closes the connection (`l-close-agent`) | Proxy connection ended before receiving CONNECT response | Proxy connection ended before receiving CONNECT response | Proxy connection ended before receiving CONNECT response | Proxy connection ended before receiving CONNECT response | Proxy connection ended before receiving CONNECT response |
| proxy config, http:// URL, proxy closes the connection (`l-close-config-http-url`) | `ECONNRESET` socket hang up | `ECONNRESET` socket hang up | `ECONNRESET` socket hang up | `ECONNRESET` socket hang up | `ECONNRESET` socket hang up |
| proxy config, proxy never answers CONNECT (`l-silent-config`) | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded | never settled | never settled |
| the same with signal: AbortSignal.timeout(3000) (`l-silent-config-signal`) | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled |
| proxy closes the connection, signal: AbortSignal.timeout(3000) (`l-close-config-signal`) | `ECONNRESET` socket hang up | `ECONNRESET` socket hang up | `ECONNRESET` socket hang up | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled |
| proxy: false + HttpsProxyAgent, proxy never answers CONNECT (`l-silent-agent`) | never settled | never settled | never settled | never settled | never settled |
| the same with signal: AbortSignal.timeout(3000) (`l-silent-agent-signal`) | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled | `ERR_CANCELED` canceled |
| proxy config, http:// URL, proxy never answers (`l-silent-config-http-url`) | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded |
| proxy never answers CONNECT, maxRedirects: 0 (`l-silent-config-no-redirects`) | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded | `ECONNABORTED` timeout of 5000ms exceeded |
