Cuando una petición de Axios en Node.js se salta el proxy, o falla al pasar por él, la causa es una de las 16 de abajo, y la mayoría depende de la versión de Axios. Axios 1.21.0 y 1.21.1 ignoran un agente con proxyEnv cuando se indica proxy: false. httpVersion: 2 y el adaptador fetch van directos en todas las versiones que los tienen. Las versiones anteriores a 1.16.1 nunca abren un túnel CONNECT para una URL https://. Cada causa incluye la salida que registramos y una solución que ejecutamos.
Probado en Node.js 24.22.2 y 26.13.0 con Axios 1.12.2, 1.19.0, 1.20.0, 1.21.0 y 1.21.1, más 1.13.6, 1.15.0, 1.16.0, 1.16.1 y 1.18.1 para encontrar dónde cambió el comportamiento, https-proxy-agent 9.1.0 y socks-proxy-agent 10.1.0, en macOS 26.5.1 arm64, el 11 de noviembre de 2026. El laboratorio es un proxy con registro y un destino HTTPS en 127.0.0.1. «Saltado» significa que el destino respondió y el proxy no registró nada. Los scripts, la tabla de resultados y los 1290 registros están en la carpeta del laboratorio (en inglés). Para configurar un proxy por primera vez, empieza por Configurar un proxy en Axios; esta página es para una configuración que no se comporta como debería.
Comprobación rápida: ¿la petición usa el proxy?
import axios from 'axios';
// Use the same client and options as the code you are debugging.
const res = await axios.get('https://api.ipify.org?format=json', {
proxy: { protocol: 'http', host: 'proxy.example', port: 8080 },
});
console.log(res.data);Ejecútalo con las opciones del código que falla y luego otra vez sin ningún proxy. Si las dos ejecuciones muestran la misma IP, la petición esquivó el proxy. Un 200 no demuestra nada: todos los saltos de esta página devolvieron 200. Si puedes leer el registro del propio proxy, mira ahí primero. En el laboratorio, cada petición https:// que pasó por el proxy dejó una línea CONNECT, y las que lo saltaron no dejaron ninguna.
Encuentra tu síntoma
| Lo que ves | Ve a |
|---|---|
Estado 200, pero la IP es la tuya y el proxy no registra nada | La petición ignora el proxy |
400, socket hang up, wrong version number, ENOTFOUND undefined o una petición que nunca termina | HTTPS a través de un proxy HTTP falla |
Request failed with status code 407 | 407 y errores de autenticación |
HTTPS_PROXY está definida pero se ignora, o se omite el proxy para un host que no debería | Variables de entorno y NO_PROXY |
| La primera petición pasa por el proxy y la redirección no | Las redirecciones salen del proxy |
protocol mismatch, o un proxy SOCKS que no puede resolver el host | Proxies SOCKS5 |
La petición ignora el proxy, sin ningún error
1. proxy: false junto a un agente con proxyEnv (Axios 1.21.0 y posteriores)
import https from 'node:https';
import axios from 'axios';
const agent = new https.Agent({ proxyEnv: { https_proxy: 'http://proxy.example:8080' } });
const res = await axios.get('https://example.com/', { proxy: false, httpsAgent: agent });
console.log(res.status);En Axios 1.20.0 el proxy del laboratorio transportó esta petición. En 1.21.0 el mismo script mostró:
200
# proxy log: (nothing)
# target log: GET /ip HTTP/1.1 directDesde 1.21.0, proxy: false significa «conéctate directamente» incluso cuando el agente tiene su propia configuración de proxy: Axios sustituye el agente por una copia sin proxyEnv (#11402, cerrada el 5 de noviembre de 2026; el cambio es el PR #11242, commit 2498c23). En el laboratorio pasó lo mismo con el interruptor del propio Node: NODE_USE_ENV_PROXY=1 o --use-env-proxy junto con proxy: false pasaron por el proxy hasta 1.20.0 y fueron directos en 1.21.0 y 1.21.1.
Solución: quita proxy: false de las peticiones que usan un agente así. Quien abrió la #11402 lo confirmó, y en el laboratorio el script sin esa opción pasó por el proxy en las diez versiones. Axios deja el proxy del entorno en manos de un agente que tiene proxyEnv (documentación de la configuración de peticiones). Mantén proxy: false junto a un agente de terceros como HttpsProxyAgent: esa pareja funcionó en todas las versiones (causa 5).
2. httpVersion: 2
import axios from 'axios';
// HTTPS_PROXY=http://proxy.example:8080 is set in the environment.
const res = await axios.get('https://example.com/', { httpVersion: 2 });
console.log(res.status);En Axios 1.21.1:
200
# proxy log: (nothing)
# target log: GET /ip HTTP/2.0 direct| Axios | objeto proxy | HTTPS_PROXY | proxy: false + HttpsProxyAgent |
|---|---|---|---|
| 1.13.6, 1.15.0, 1.16.0 | ERR_HTTP2_ERROR | ERR_HTTP2_ERROR | saltado sin error |
| 1.16.1, 1.18.1, 1.19.0 | saltado sin error | saltado sin error | saltado sin error |
| 1.20.0, 1.21.0, 1.21.1 | ERR_NOT_SUPPORT | saltado sin error | saltado sin error |
Axios 1.12.2 no tiene soporte de HTTP/2 e ignoró la opción. El aviso de seguridad GHSA-3pq3-5fj3-cg6v (CVE-2026-101898, entrada de GitLab) abarca desde 1.13.0 hasta 1.20.0, sin incluirla: la ruta HTTP/2 se conecta por su cuenta y descarta el proxy. El laboratorio reprodujo el salto silencioso de 1.16.1 a 1.19.0. En 1.13.6, 1.15.0 y 1.16.0 la petición falló con Protocol error tras enviar bytes de HTTP/2 al proxy, así que allí el fallo fue visible, no silencioso.
La corrección de 1.20.0 rechaza un objeto proxy explícito con HTTP/2 requests with a proxy are not supported. No cubre el entorno: el PR #11141 dice que HTTP/2 sigue siendo directo cuando el proxy viene solo de variables de entorno o de un agente, y la documentación dice que las peticiones HTTP/2 no se pueden enviar por un proxy. NODE_USE_ENV_PROXY=1 también fue directo.
Solución: quita httpVersion: 2 de toda petición que deba usar el proxy. La misma petición sin esa opción pasó por el proxy con HTTP/1.1 en 1.16.1 y posteriores.
3. El adaptador fetch
Con adapter: 'fetch', un objeto proxy, HTTPS_PROXY y un httpsAgent se saltaron sin error en las diez versiones y en las dos líneas de Node. La documentación marca proxy como solo para Node.js, y en el laboratorio solo el adaptador HTTP predeterminado leyó esa opción, las variables de proxy o los agentes.
Solución: quita adapter: 'fetch', o deja que Node envíe su propio fetch por el proxy: con NODE_USE_ENV_PROXY=1 y HTTPS_PROXY definida, el adaptador fetch pasó por el proxy en Node 24.22.2 y 26.13.0. proxy: false no lo desactivó. Si el error es fetch failed, consulta cómo arreglar fetch failed en Node.js detrás de un proxy e invalid onError method en Node.js 26.
4. El agente está en la opción equivocada
Un HttpsProxyAgent pasado solo como httpAgent, con una URL https://: saltado sin error en todas las versiones. Axios usa httpAgent para las peticiones http:// y httpsAgent para las peticiones https:// (README).
Solución: define las dos opciones, como hace el ejemplo de SOCKS de más abajo.
HTTPS a través de un proxy HTTP falla
5. Axios antes de 1.16.1 no envía CONNECT
Con un objeto proxy o con HTTPS_PROXY, Axios 1.12.2, 1.13.6, 1.15.0 y 1.16.0 no pidieron un túnel al proxy. El proxy del laboratorio recibió la URL completa en una petición normal:
AxiosError: Request failed with status code 400
# exit code: 1
# proxy log: A GET https://target.test:<T>/ip -> 400
# target log: (nothing)Nuestro proxy rechaza una petición así con 400. Un proxy del laboratorio que corta la conexión produjo socket hang up (ECONNRESET), el error descrito en la #4531. Esa incidencia se abrió en marzo de 2022 y se cerró el 30 de julio de 2025 en una limpieza que pedía a sus autores volver a probar. La #3384, cerrada en junio de 2022, describe la misma configuración con un error de handshake propio de un proxy concreto que no pudimos reproducir.
Axios 1.16.1 cambió esto: según el PR #10858, Axios usa un túnel CONNECT para los destinos HTTPS en lugar de reenviar al proxy las URL, las cabeceras y los cuerpos en texto plano. A partir de 1.16.1, todos estos casos pasaron por un túnel.
Solución: actualiza a 1.16.1 o posterior. Si no puedes, usa un agente de proxy y desactiva la gestión de proxy del propio Axios. Esto funcionó en las diez versiones, incluida 1.12.2:
import axios from 'axios';
import { HttpsProxyAgent } from 'https-proxy-agent';
const agent = new HttpsProxyAgent('http://proxy.example:8080');
const res = await axios.get('https://example.com/', {
proxy: false, // Axios adds no proxy handling of its own
httpsAgent: agent, // the agent opens the CONNECT tunnel
signal: AbortSignal.timeout(15000),
});
console.log(res.status);6. wrong version number: el esquema del proxy es incorrecto o falta
write EPROTO <id>:error:0A00010B:SSL routines:tls_validate_record_header:wrong version number:../deps/openssl/openssl/ssl/record/methods/tlsany_meth.c:78:El cliente habla TLS con un puerto del proxy que habla HTTP sin cifrar. En todas las versiones el laboratorio obtuvo este error con protocol: 'https' en el objeto proxy, con HTTPS_PROXY=https://127.0.0.1:8080, con HTTPS_PROXY=127.0.0.1:8080 sin ningún esquema y con new HttpsProxyAgent('https://…'). Hasta 1.16.0, un objeto proxy sin protocol fallaba igual; desde 1.16.1 funcionó.
protocol y el esquema de la URL describen la conexión con el proxy, no con el sitio: usa https solo cuando el propio proxy sirve TLS (README). La #6198 describe este error con un HttpsProxyAgent; se cerró en agosto de 2025 por falta de una reproducción, y su configuración con una URL de proxy http:// funcionó en nuestro laboratorio.
Solución: escribe protocol: 'http', o http:// en la URL, para un proxy HTTP corriente. SSL: wrong version number a través de un proxy trata el mismo error en otros clientes.
7. El proxy es una cadena, o el esquema está dentro de host
proxy: 'http://proxy.example:8080'(una cadena):getaddrinfo ENOTFOUND undefineddesde 1.16.1,connect ECONNREFUSED ::1:443antes.proxy: { host: 'http://proxy.example', port: 8080 }:Invalid URL(ERR_INVALID_URL) desde 1.16.1,getaddrinfo ENOTFOUND http://127.0.0.1antes.
Ninguna de las dos llegó al proxy. La #2072, cerrada en 2020, usa la segunda forma en código de navegador, donde la opción proxy no se aplica en absoluto (documentación); no probamos navegadores.
Solución: pasa un objeto con el nombre de host sin esquema en host, un port numérico o de texto y el esquema en protocol.
8. La petición nunca termina
Desde Axios 1.16.1, con un objeto proxy o con HTTPS_PROXY, un proxy que cerró la conexión tras el CONNECT, o que nunca lo respondió, dejó la petición pendiente: sin respuesta y sin error tras 15 segundos, aunque se había indicado timeout: 5000. Antes de 1.16.1 los mismos casos se rechazaban con socket hang up o timeout of 5000ms exceeded. Con proxy: false y un HttpsProxyAgent, una conexión cerrada se rechazó con Proxy connection ended before receiving CONNECT response, y un proxy mudo dejó la petición pendiente en las diez versiones. Las URL http:// se rechazaron con normalidad, con timeout of 5000ms exceeded o socket hang up. El 11 de noviembre de 2026 no encontramos ninguna incidencia de Axios sobre esto.
Solución: da a cada petición por proxy un plazo propio. signal: AbortSignal.timeout(3000) terminó cada caso pendiente a los 3 segundos con canceled (ERR_CANCELED). maxRedirects: 0 también hizo que timeout funcionara con el túnel integrado, un caso que mencionan las notas de 1.16.0.
407 y errores de autenticación
Una contraseña incorrecta, o ninguna, devolvió lo mismo en todas las versiones, vinieran las credenciales de proxy.auth, de HTTPS_PROXY o de la URL de un HttpsProxyAgent: Request failed with status code 407, con error.code igual a ERR_BAD_REQUEST y error.response.status igual a 407. El proxy registró una petición, respondida con 407, y el destino no vio nada. Un proxy SOCKS5 no tiene código de estado: allí una contraseña incorrecta dio Socks5 Authentication failed.
9. Las credenciales están en el lugar equivocado
Poner el usuario y la contraseña del proxy en la opción auth de nivel superior devolvió 407, y el registro del proxy muestra que no recibió credenciales. La opción auth de nivel superior es para el sitio; las credenciales del proxy van en proxy.auth (README). Con proxy.auth, desde 1.16.1 el proxy autenticó el CONNECT y el destino nunca vio una cabecera Proxy-Authorization, tampoco en una redirección a un segundo host.
10. Caracteres especiales codificados de forma incorrecta
El proxy del laboratorio esperaba la contraseña p@ss/w0rd#1:
| Dónde va la contraseña | Cómo se escribe | Resultado |
|---|---|---|
proxy.auth.password | tal cual | por el proxy (1.16.1 y posteriores) |
proxy.auth.password | con codificación porcentual | 407: el proxy recibió p%40ss%2Fw0rd%231 |
URL de HTTPS_PROXY | tal cual | getaddrinfo ENOTFOUND ss |
URL de HTTPS_PROXY | con codificación porcentual | 407: el proxy recibió p%40ss%2Fw0rd%231 |
URL de HttpsProxyAgent | con codificación porcentual | por el proxy (todas las versiones) |
Pegada tal cual, la @ termina las credenciales antes de tiempo y ss pasa a ser el host. Con codificación porcentual, la URL se analiza bien, pero Axios copia de ella el usuario y la contraseña sin decodificarlos (http.js en 1.21.1). Por eso, en las versiones probadas, una contraseña con caracteres reservados no pudo pasar por HTTPS_PROXY de ninguna forma.
Solución: pásala en proxy.auth sin codificar, o en la URL de un agente con codificación porcentual. Las dos peticiones de abajo pasaron por el proxy de 1.19.0 a 1.21.1:
import axios from 'axios';
import { HttpsProxyAgent } from 'https-proxy-agent';
const user = process.env.PROXY_USER;
const pass = process.env.PROXY_PASS;
// In the proxy object: the raw password, not percent-encoded.
const a = await axios.get('https://example.com/', {
proxy: { protocol: 'http', host: 'proxy.example', port: 8080, auth: { username: user, password: pass } },
});
// In a proxy URL for an agent: percent-encode both parts.
const url = `http://${encodeURIComponent(user)}:${encodeURIComponent(pass)}@proxy.example:8080`;
const b = await axios.get('https://example.com/', { proxy: false, httpsAgent: new HttpsProxyAgent(url) });
console.log(a.status, b.status);Para un 407 que persiste con las credenciales correctas, por ejemplo por una lista de IP permitidas o por el formato del usuario, consulta cómo arreglar el error de proxy 407.
Las variables de entorno no se aplican, o NO_ PROXY coincide mal
Lo que Axios leyó en el laboratorio, en las diez versiones: HTTPS_PROXY o https_proxy para las URL https://, HTTP_PROXY o http_proxy para las URL http://, y ALL_PROXY o all_proxy cuando falta la específica. Con las dos grafías definidas, ganó la minúscula. Las variables se leen en el momento de la petición, así que asignar process.env.HTTPS_PROXY en el código antes de la petición funcionó. Un objeto proxy tuvo prioridad sobre las variables y sobre NO_PROXY. Antes de 1.16.1 las variables se leían igual, pero las peticiones https:// fallaban después como en la causa 5.
11. La variable no corresponde al esquema de la URL
Con solo HTTP_PROXY definida, una petición https:// fue directa sin ningún error, en todas las versiones. Con solo HTTPS_PROXY, lo mismo hizo una petición http://.
Solución: define las dos, normalmente con la misma URL de proxy http://. Variables de entorno de proxy compara cómo las leen otros clientes.
12. Un proxy del entorno anula tu agente
Con HTTPS_PROXY definida, un HttpsProxyAgent o un SocksProxyAgent pasado como httpsAgent sin proxy: false se ignoró: desde 1.16.1 la petición pasó por el proxy del entorno, no por el del agente. Un objeto proxy junto al agente ganó de la misma manera. Basta un ejecutor de CI o un contenedor que defina HTTPS_PROXY para que tu tráfico salga por un proxy distinto del que indica tu código.
Solución: proxy: false en toda petición que use un agente de proxy de terceros. Con esa opción, el proxy del agente transportó la petición en las diez versiones, hubiera lo que hubiera en el entorno.
13. NO_PROXY coincide de forma distinta según la versión
Con una variable de proxy definida y target.test como host de la URL:
NO_PROXY | Ruta | Versiones |
|---|---|---|
target.test, TARGET.TEST, .test, *.test, *, target.test:PORT con el puerto de la URL | directa | todas |
other.test target.test o other.test, target.test | directa | todas |
.target.test, test, get.test, target.test:9999, https://target.test | proxy | todas |
target.test, cuando la URL dice target.test. con un punto final | proxy en 1.12.2 y 1.13.6, directa desde 1.15.0 | corregido en 1.15.0 |
127.0.0.0/8, host de la URL 127.0.0.1 | proxy hasta 1.19.0, directa desde 1.20.0 | corregido en 1.20.0 |
localhost, host de la URL 127.0.0.1 | proxy hasta 1.15.0, directa desde 1.16.0 | cambió en 1.16.0 |
La fila del punto final es GHSA-3p68-rc4w-qgx5, corregido en 1.15.0. La fila de CIDR es GHSA-44g4-m2mj-wpvx (CVE-2026-101899), corregido en 1.20.0; el aviso indica como afectadas las versiones 1.15.0 y posteriores, y en el laboratorio 1.12.2 y 1.13.6 también ignoraron la entrada CIDR. Con NO_PROXY sin definir, las peticiones a localhost y a 127.0.0.1 pasaron por el proxy en todas las versiones. Coincidencia de NO_PROXY, probada tiene la misma matriz para otros clientes.
Las redirecciones salen del proxy
14. Una redirección cambia de esquema, o llega a un host de NO_PROXY
El destino del laboratorio responde 302 hacia un segundo host.
- De
http://ahttps://, solo conHTTP_PROXY: el primer salto pasó por el proxy y el segundo fue directo, en todas las versiones. Lo mismo ocurrió conproxy: falsey solohttpAgentdefinido. Con los dos agentes, o desde 1.16.1 con las dos variables, los dos saltos pasaron por el proxy. - De
https://ahttps://en otro host: los dos saltos pasaron por el proxy con un objetoproxy, conHTTPS_PROXYy con un agente, desde 1.16.1. Con autenticación de proxy, las dos peticionesCONNECTllevaron las credenciales. - Redirección a un host incluido en
NO_PROXY: en 1.21.0 y 1.21.1 el segundo salto fue directo. De 1.16.1 a 1.20.0 siguió pasando por el proxy. Con un objetoproxyexplícito, los dos saltos pasaron por el proxy desde 1.16.1.
Solución: define las dos variables o los dos agentes. Si una redirección no debe salir nunca del proxy, usa un objeto proxy o un par de agentes con proxy: false, y no incluyas ese host en NO_PROXY.
Proxies SOCKS5
15. socks5:// en la opción proxy o en HTTPS_PROXY
Axios no tiene cliente SOCKS. proxy: { protocol: 'socks5', … } y HTTPS_PROXY=socks5://… fallaron con protocol mismatch (ERR_ASSERTION) hasta 1.16.0. Desde 1.16.1 Axios envió una línea HTTP CONNECT al puerto SOCKS, el servidor SOCKS del laboratorio cerró la conexión y la petición nunca terminó (causa 8).
Solución: un agente SOCKS en las dos opciones de agente, con proxy: false (causa 12). Así la petición pasó por el proxy SOCKS5 del laboratorio en las diez versiones:
import axios from 'axios';
import { SocksProxyAgent } from 'socks-proxy-agent';
// socks5h: the proxy resolves the hostname. socks5: this machine does.
const agent = new SocksProxyAgent('socks5h://proxy.example:1080');
const res = await axios.get('https://example.com/', {
proxy: false,
httpAgent: agent,
httpsAgent: agent,
signal: AbortSignal.timeout(15000),
});
console.log(res.status);16. socks5 en lugar de socks5h
Con socks5://, el servidor SOCKS del laboratorio recibió una dirección IP: el cliente había resuelto el nombre por su cuenta. Con socks5h:// recibió el nombre de host (README de socks-proxy-agent). Para un nombre que solo el proxy puede resolver, socks5:// falló con getaddrinfo ENOTFOUND proxy-only.test y socks5h:// funcionó. SOCKS5 frente a SOCKS5h explica qué más revela la consulta DNS local.
Una configuración que funciona para cada necesidad
Las tres pasaron por el proxy del laboratorio en Axios 1.19.0, 1.20.0, 1.21.0 y 1.21.1, en las dos líneas de Node. En 1.12.2 solo lo hizo la tercera.
Un proxy fijo en el código (Axios 1.16.1 o posterior):
import axios from 'axios';
const client = axios.create({
proxy: {
protocol: 'http', // how to reach the proxy, not the site
host: 'proxy.example',
port: 8080,
auth: { username: process.env.PROXY_USER, password: process.env.PROXY_PASS },
},
});
const res = await client.get('https://example.com/', { signal: AbortSignal.timeout(15000) });
console.log(res.status);Un proxy corporativo desde el entorno (Axios 1.16.1 o posterior). Define las variables fuera del código:
export HTTPS_PROXY=http://proxy.example:8080
export HTTP_PROXY=http://proxy.example:8080
export NO_PROXY=localhost,127.0.0.1import axios from 'axios';
// Started with HTTPS_PROXY, HTTP_PROXY and NO_PROXY in the environment.
// No proxy option, no agent, no httpVersion, default adapter.
const res = await axios.get('https://example.com/', { signal: AbortSignal.timeout(15000) });
console.log(res.status);Un proxy distinto por petición (todas las versiones probadas):
import axios from 'axios';
import { HttpsProxyAgent } from 'https-proxy-agent';
const agents = new Map();
const agentFor = (proxyUrl) => {
if (!agents.has(proxyUrl)) agents.set(proxyUrl, new HttpsProxyAgent(proxyUrl));
return agents.get(proxyUrl);
};
const viaProxy = (url, proxyUrl) =>
axios.get(url, { proxy: false, httpsAgent: agentFor(proxyUrl), signal: AbortSignal.timeout(15000) });
const first = await viaProxy('https://example.com/', 'http://proxy-a.example:8080');
const second = await viaProxy('https://example.com/', 'http://proxy-b.example:8080');
console.log(first.status, second.status);En el laboratorio las dos peticiones salieron por dos proxies distintos. Para las URL http://, añade un HttpProxyAgent de http-proxy-agent como httpAgent.
Una salvaguarda para tus pruebas
La mayoría de las causas anteriores devuelven 200, así que una batería de pruebas normal sigue en verde cuando una actualización o una opción nueva empieza a saltarse el proxy. Esta prueba arranca un proxy de sustitución que registra lo que le llega y lo rechaza, y después envía una petición con el cliente que construye tu aplicación:
import assert from 'node:assert/strict';
import { once } from 'node:events';
import http from 'node:http';
import { test } from 'node:test';
import { createClient } from './client.mjs';
test('the HTTP client sends requests through the proxy', async () => {
const seen = [];
// A stand-in proxy: it records what arrives and refuses it, so nothing leaves the machine.
const proxy = http.createServer((req, res) => {
seen.push(`${req.method} ${req.url}`);
res.writeHead(503).end();
});
proxy.on('connect', (req, socket) => {
seen.push(`CONNECT ${req.url}`);
socket.end('HTTP/1.1 503 Service Unavailable\r\n\r\n');
});
proxy.listen(0, '127.0.0.1');
await once(proxy, 'listening');
const client = createClient(`http://127.0.0.1:${proxy.address().port}`);
// .invalid never resolves, so a request that skips the proxy cannot reach a real site.
await client.get('https://guard.invalid/', { signal: AbortSignal.timeout(5000) }).catch(() => {});
proxy.close();
assert.deepEqual(seen, ['CONNECT guard.invalid:443']);
});createClient(proxyUrl) es tu propia fábrica. Con el cliente por petición de arriba, node --test pasó en las cinco versiones principales. Después de añadir adapter: 'fetch' al mismo cliente, falló:
not ok 1 - the HTTP client sends requests through the proxy
Expected values to be strictly deep-equal:
+ actual - expected
+ []
- [
- 'CONNECT guard.invalid:443'
- ]
# tests 1
# pass 0
# fail 1
# exit code: 1Versiones que usar o evitar
- Usa 1.21.1, la última versión en la fecha de la prueba, o al menos 1.20.0. Comprueba dos cosas tras actualizar:
proxy: falsejunto a un agente conproxyEnv(causa 1) y las redirecciones a hosts deNO_PROXY(causa 14). - Antes de 1.16.1: sin túnel CONNECT para las URL
https://a través de un proxy HTTP (causa 5). Usa el patrón del agente o actualiza. - De 1.13.0 a 1.19.0 con
httpVersion: 2: dentro del rango de GHSA-3pq3-5fj3-cg6v. En 1.20.0 y posteriores, HTTP/2 sigue ignorandoHTTPS_PROXY(causa 2). - Antes de 1.15.0 y antes de 1.20.0:
NO_PROXYno reconoce, respectivamente, los hosts con punto final y los rangos CIDR (causa 13). - Node.js: 24.22.2 y 26.13.0 encaminaron todos los casos igual. La única diferencia: con el adaptador fetch, Node 26 negoció HTTP/2 con el destino del laboratorio y Node 24 usó HTTP/1.1.
Preguntas frecuentes
¿Por qué Axios ignora HTTPS_PROXY?
En el laboratorio lo hizo por seis motivos: proxy: false en la petición, httpVersion: 2, adapter: 'fetch', un objeto proxy que tiene prioridad, una coincidencia en NO_PROXY o una URL http://, que lee HTTP_PROXY.
¿Sigo necesitando https-proxy-agent con Axios?
No para un único proxy HTTP en Axios 1.16.1 o posterior: el objeto proxy y HTTPS_PROXY abrieron el túnel por sí solos. Lo necesitas en versiones anteriores, y es la forma más sencilla de usar un proxy distinto por petición.
¿Axios admite proxies SOCKS5?
No mediante proxy ni HTTPS_PROXY. Pasa un SocksProxyAgent como httpAgent y httpsAgent con proxy: false.
¿Por qué mi petición de Axios se queda colgada con un proxy aunque haya un timeout?
En las versiones probadas, timeout no cubrió un proxy que no responde al CONNECT (causa 8). Añade signal: AbortSignal.timeout(ms).
¿Funciona la opción proxy de Axios en el navegador?
No. La documentación marca proxy como solo para Node.js; un navegador usa el proxy del sistema operativo o el suyo propio.
Guías relacionadas
- Configurar un proxy en Axios es la página de configuración: una comprobación explícita del proxy y qué capa decide la ruta.
- Variables de entorno de proxy compara cómo las leen curl, Requests y Node.
- Cómo arreglar el error de proxy 407 trata un 407 que no tiene que ver con la codificación.
- fetch failed: invalid onError method en Node.js 26 es el fallo de los agentes de proxy de undici en Node 26.
- Cómo arreglar TypeError: fetch failed en Node.js detrás de un proxy lee la cadena de errores cuando usas
fetch. - Coincidencia de NO_PROXY, probada tiene las reglas de coincidencia de otros clientes.
Prueba la solución con una IP real. ipvolt vende proxies residenciales desde US$2.20 por GB y un proxy móvil dedicado desde US$9 al día. Pon el proxy en la configuración de arriba y ejecuta la comprobación rápida. Comprueba un proxy ahora.
Fuentes y lecturas adicionales
Referencias técnicas usadas para esta guía. Consulta la documentación de tu versión instalada y la configuración compatible de tu proveedor.
- axios/axios#11402: axios@1.21.0 breaks custom https.Agent with proxyEnv enabled
- axios/axios#11242: align request handling across runtimes (direct agents for proxy: false)
- axios/axios commit 2498c23
- GHSA-3pq3-5fj3-cg6v (CVE-2026-101898): HTTP/2 adapter bypasses configured DNS lookup and proxy controls
- GitLab advisory database: CVE-2026-101898
- axios/axios#11141: HTTP/2 proxy handling and CIDR matching for NO_PROXY
- GHSA-3p68-rc4w-qgx5: NO_PROXY hostname normalization bypass
- GHSA-44g4-m2mj-wpvx (CVE-2026-101899): CIDR-form NO_PROXY entries are ignored
- axios/axios#4531: Proxy support does not work properly with CONNECT on https requests
- axios/axios#3384: HTTPS over HTTP Proxy Fails
- axios/axios#2072: Axios proxy is not working
- axios/axios#6198: https proxy agent not working as expected
- axios/axios#10858: CONNECT tunnelling for HTTPS targets
- Axios 1.16.0 release notes
- Axios 1.16.1 release notes
- Axios 1.20.0 release notes
- Axios 1.21.0 release notes
- Axios 1.21.1 release notes
- Axios docs: request config (proxy, httpAgent, httpsAgent, environment variables)
- Axios 1.21.1 README: request config
- Axios 1.21.1: HTTP adapter source
- Node.js HTTP: built-in proxy support and the Agent proxyEnv option
- Node.js CLI: NODE_USE_ENV_PROXY=1
- Node.js CLI: --use-env-proxy
- socks-proxy-agent README