TypeError: fetch failed у Node.js через проксі
Вбудований fetch у Node.js показує загальний текст «fetch failed», а справжня причина лежить у полі cause. Через проксі до цього додається ще одна пастка: fetch за замовчуванням не читає змінні проксі.
Оновлено · Редакція Prokso
- fetch failed — лише обгортка: справжня причина лежить у err.cause
- Вбудований fetch читає HTTP_PROXY тільки з NODE_USE_ENV_PROXY=1 або --use-env-proxy
- Найпростіше передати dispatcher з ProxyAgent з undici прямо у fetch
Що означає помилка
За документацією Node.js, глобальний fetch побудований на бібліотеці undici. Коли запит не вдається на рівні мережі, undici відхиляє його помилкою TypeError: fetch failed, а початкову помилку кладе в error.cause. Тому дивитися треба саме туди: console.log(err.cause).
У cause буде, наприклад, ECONNREFUSED, ENOTFOUND, тайм-аут підключення з кодом UND_ERR_CONNECT_TIMEOUT або відповідь проксі. Якщо проксі не прийняв логін для HTTPS-адреси, undici пише Proxy response (407) !== 200 when HTTP Tunneling.
Друга пастка: змінні HTTP_PROXY і HTTPS_PROXY вбудований fetch читає лише тоді, коли ввімкнено вбудовану підтримку проксі. Змінна NODE_USE_ENV_PROXY=1 з'явилася в Node.js 24.0.0 і 22.21.0, прапорець --use-env-proxy — у 24.5.0 і 22.21.0; документація позначає цю можливість як таку, що активно розвивається. Без цього запит іде напряму, повз проксі.
Причини
- Проксі не підключено. Змінні середовища задано, але fetch їх не читає без NODE_USE_ENV_PROXY=1 або --use-env-proxy, і запит іде з вашого IP.
- Неправильний хост або порт. У cause видно ECONNREFUSED або ENOTFOUND: помилка в gw.prokso.com чи порт поза 823, 824 і 10000–20000.
- Логін або пароль не прийнято. Для HTTPS-адрес у cause приходить «Proxy response (407) !== 200 when HTTP Tunneling». Відповідь шлюзу Prokso в цьому випадку — «HTTP/1.1 407 NO_USER».
- SOCKS5-порт для HTTP-агента. ProxyAgent з адресою http:// на порт 824 говорить HTTP із SOCKS5-портом, і з'єднання не встановлюється.
- Сайт не відповів вчасно. Тайм-аут підключення або читання: проксі чи сайт не встигли відповісти.
Як виправити
- Виведіть причину:
catch (err) { console.log(err.cause) }. Код у cause підкаже, з якого кроку почати. - Підключіть проксі явно: встановіть пакет undici і передайте в fetch
dispatcher: new ProxyAgent('http://ЛОГІН:ПАРОЛЬ@gw.prokso.com:823'). Документація Node.js підтверджує, що глобальний fetch приймає dispatcher, сумісний з undici. - Щоб брати проксі зі змінних середовища, використайте
EnvHttpProxyAgentз undici черезsetGlobalDispatcher()або запустіть Node.js ізNODE_USE_ENV_PROXY=1чи--use-env-proxy, якщо ваша версія це підтримує. - Для 407 скопіюйте логін і пароль з особистого кабінету заново. Якщо в паролі є спецсимволи, закодуйте їх через
encodeURIComponent. Синтаксис логіна й порти зібрано на сторінці логін, порти й параметри. - Для HTTP-агента беріть порт 823 або порт 10000–20000 для фіксованого IP. Інші варіанти підключення — в інструкції Node.js.
- Якщо в cause тайм-аут, зменште кількість паралельних запитів і див. сторінку тайм-аут проксі.
Як перевірити, що все запрацювало
Зробіть fetch на https://prokso.com/ip з тим самим dispatcher. Якщо у JSON IP і країна проксі, підключення працює. Сам рядок можна окремо перевірити в перевірці проксі.
Діагностика за 2 хвилини
Спершу вставте рядок у перевірку проксі. Якщо там проксі працює, причина в програмі чи її налаштуваннях. Якщо ні — перевірте рядок з терміналу:
curl -v -x "http://ЛОГІН:ПАРОЛЬ@gw.prokso.com:823" https://api.ipify.org
- Рядок
< HTTP/1.1 407одразу післяCONNECT— відповідає проксі. Назва після коду, наприкладNO_USER, підказує причину. - Проксі відповів на
CONNECTкодом 200, а далі прийшов інший код — проксі працює, цю відповідь дав сайт. - Жодної відповіді, лише тайм-аут — з'єднання не дійшло до проксі: перевірте хост, порт і мережу.
Інструкції, де трапляється ця помилка
Питання й відповіді
Чому fetch працює, але IP у відповіді мій?
Найімовірніше, проксі просто не підключено: вбудований fetch не читає HTTP_PROXY без NODE_USE_ENV_PROXY=1 або --use-env-proxy. Передайте dispatcher явно.
Чи підтримує NODE_USE_ENV_PROXY SOCKS5?
Документація Node.js описує для вбудованої підтримки лише адреси проксі HTTP і HTTPS. Для SOCKS5 використовуйте окремий агент або бібліотеку.
У cause помилка сертифіката. Це проксі?
Порт 823 не підміняє сертифікати сайтів, тож причину шукайте в системі чи на сайті. Див. <a href="/errors/ssl-certificate-errors">помилки SSL-сертифіката</a>.
Як дізнатися версію undici у Node.js?
За документацією Node.js — через властивість process.versions.undici.
Інші помилки проксі
Резидентські $1.59, мобільні $2.50, серверні $0.65 за 1 ГБ
Реєстрація за хвилину, доступи одразу після оплати.