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-портом, і з'єднання не встановлюється.
  • Сайт не відповів вчасно. Тайм-аут підключення або читання: проксі чи сайт не встигли відповісти.

Як виправити

  1. Виведіть причину: catch (err) { console.log(err.cause) }. Код у cause підкаже, з якого кроку почати.
  2. Підключіть проксі явно: встановіть пакет undici і передайте в fetch dispatcher: new ProxyAgent('http://ЛОГІН:ПАРОЛЬ@gw.prokso.com:823'). Документація Node.js підтверджує, що глобальний fetch приймає dispatcher, сумісний з undici.
  3. Щоб брати проксі зі змінних середовища, використайте EnvHttpProxyAgent з undici через setGlobalDispatcher() або запустіть Node.js із NODE_USE_ENV_PROXY=1 чи --use-env-proxy, якщо ваша версія це підтримує.
  4. Для 407 скопіюйте логін і пароль з особистого кабінету заново. Якщо в паролі є спецсимволи, закодуйте їх через encodeURIComponent. Синтаксис логіна й порти зібрано на сторінці логін, порти й параметри.
  5. Для HTTP-агента беріть порт 823 або порт 10000–20000 для фіксованого IP. Інші варіанти підключення — в інструкції Node.js.
  6. Якщо в 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 ГБ

Реєстрація за хвилину, доступи одразу після оплати.

Створити акаунт