.bp-clean-small-figure{max-width:540px!important;width:100%!important;margin:22px auto!important;padding:10px!important;border-radius:20px!important;background:#fff!important;box-shadow:0 10px 28px rgba(7,18,5,.10)!important}.bp-clean-small-figure img,.bp-clean-small-image{display:block!important;width:100%!important;height:auto!important;border-radius:16px!important}.bp-clean-small-figure figcaption{font-size:14px!important;line-height:1.45!important;color:#4b5563!important;margin-top:10px!important;text-align:center!important}

JavaScript HTTP client guide

Node.js Proxy Guide: Fetch, Axios, Undici and Environment Variables

Configure private proxies in modern Node.js with built-in environment support, Undici dispatchers, Axios, secure credentials, bypass rules and error handling.

Node.js HTTP proxy configuration choices
Choose one proxy mechanism for each Node.js code path, secure its configuration and verify the actual route.

Short answer: how to use proxies in Node.js

Modern Node.js releases can use HTTP_PROXY, HTTPS_PROXY and NO_PROXY through built-in proxy support when explicitly enabled. Undici also provides ProxyAgent and EnvHttpProxyAgent for fetch-style requests. Axios has its own request configuration. Choose one routing mechanism for a code path, keep credentials in secrets, and verify the final exit.

Proxy behavior is version-sensitive. The current Node.js HTTP documentation marks built-in proxy support as active development and documents the versions where it was added. Check the runtime used by local development, CI and production before copying an example.

Do not stack proxy mechanisms blindly. Environment variables, a global dispatcher and a library-specific agent can conflict. Pick one owner for routing and document bypass rules.

Built-in Node.js proxy support

On a Node release that supports it, enable environment proxy routing at startup with NODE_USE_ENV_PROXY=1 or --use-env-proxy. Then normal fetch and supported HTTP clients can read the proxy variables.

# Linux or macOS
NODE_USE_ENV_PROXY=1 
HTTPS_PROXY="http://user:pass@proxy.example:8080" 
NO_PROXY="localhost,127.0.0.1,.internal.example" 
node app.mjs

# Or use the command-line flag
HTTPS_PROXY="http://proxy.example:8080" 
node --use-env-proxy app.mjs
const response = await fetch('https://api.ipify.org?format=json', {
  signal: AbortSignal.timeout(30_000)
});

if (!response.ok) {
  throw new Error(`IP check failed with ${response.status}`);
}

console.log(await response.json());

Node documents lower- and uppercase proxy variables and their precedence. It also supports exact hosts, suffixes, wildcards, IPs, ranges and host-port pairs in NO_PROXY. Test bypass rules: an overly broad entry can silently send sensitive traffic directly.

Never store an authenticated proxy URL in a checked-in .env file. The official environment variables guide explains process.env and dotenv syntax, but secret storage and deployment permissions remain your responsibility.

Use Undici EnvHttpProxyAgent

Undici’s EnvHttpProxyAgent reads HTTP, HTTPS and NO_PROXY values and can be supplied as a local dispatcher or installed globally. A local dispatcher makes the routing decision explicit for one request group.

import {
  EnvHttpProxyAgent,
  fetch
} from 'undici';

const dispatcher = new EnvHttpProxyAgent();

try {
  const response = await fetch(
    'https://api.ipify.org?format=json',
    {
      dispatcher,
      signal: AbortSignal.timeout(30_000)
    }
  );

  if (!response.ok) {
    throw new Error(`Unexpected status ${response.status}`);
  }

  console.log(await response.json());
} finally {
  await dispatcher.close();
}

The official EnvHttpProxyAgent documentation describes variable precedence, bypass matching and local or global dispatcher use. Close a locally created dispatcher during application shutdown so connections do not remain open unexpectedly.

Node.js HTTP proxy environment configuration
Make HTTP_PROXY, HTTPS_PROXY and NO_PROXY explicit, secure and testable across environments.

Configure an HTTP proxy in Axios

Axios exposes a request-level proxy object for HTTP proxy routing in Node.js. This is useful when one client instance owns the policy. Do not also install a conflicting global agent unless you understand which option wins.

import axios from 'axios';

const client = axios.create({
  timeout: 30_000,
  proxy: {
    protocol: 'http',
    host: process.env.PROXY_HOST,
    port: Number(process.env.PROXY_PORT),
    auth: process.env.PROXY_USERNAME
      ? {
          username: process.env.PROXY_USERNAME,
          password: process.env.PROXY_PASSWORD || ''
        }
      : undefined
  }
});

const { data, status } = await client.get(
  'https://api.ipify.org?format=json'
);

console.log(status, data);

The official Axios request configuration documents proxy and environment behavior. SOCKS usually requires a compatible agent rather than the HTTP proxy object. Confirm the library and agent documentation instead of changing the protocol label in a URL and assuming support.

Design NO_PROXY rules carefully

NO_PROXY is a routing policy, not a convenience string. Add local development hosts, private services or destinations that must connect directly only when that behavior is intentional. Test exact hosts, subdomains and ports separately.

Pattern Typical meaning Risk to check
localhost Bypass local hostname Does not always imply every loopback IP form
127.0.0.1 Bypass IPv4 loopback Add IPv6 loopback if the application uses it
.internal.example Bypass matching domain suffix Confirm exact implementation semantics
example.com:8443 Bypass one host and port Other ports may still use the proxy
* Bypass everything Effectively disables proxy routing

Log whether a request used the named routing policy, but do not log the full authenticated proxy URL. A safe record includes a masked proxy ID, destination hostname, bypass decision, duration, status and error category.

Handle Node.js proxy errors without losing evidence

  • Use a total timeout or AbortSignal for every external request.
  • Preserve error code, cause and proxy stage before wrapping the error.
  • Distinguish proxy 407 from target 401 or 403.
  • Do not retry DNS, TLS and authentication failures identically.
  • Retry only safe operations with bounded backoff and jitter.
  • Respect 429 and Retry-After from the target service.
  • Close custom agents and dispatchers during shutdown.

A connection timeout can come from DNS, proxy reachability, the CONNECT tunnel or target. Test the proxy separately with the proxy tester, then reproduce one request with the cURL proxy guide. The error code guide helps classify the result.

Node.js proxy request failure layers
Keep DNS, connection, proxy authentication, TLS and target HTTP evidence separate.

Proxy pools and request assignment

A Node.js service should acquire proxies from one pool component rather than choosing a random array entry in every function. The pool owns health state, location, concurrency, quarantine and credentials. A request receives a lease, uses the proxy for the required session, records the result and releases the lease.

For a stateful sequence, reuse the same dispatcher or proxy assignment. For independent read requests, a new job may receive a different healthy proxy. Connection reuse can keep traffic on an existing route, so rotation must happen at a boundary the HTTP client actually respects.

Use proxy pool management for health and quarantine, and proxy pool sizing for concurrency and reserve. Do not use a larger pool to evade a destination’s rate limit.

Credential and logging checklist

  • Store proxy credentials in a secret manager or protected runtime environment.
  • Encode URL username and password safely when constructing a URL.
  • Redact Proxy-Authorization and authenticated URLs from errors.
  • Restrict secret access to the service and environment that need it.
  • Rotate credentials when staff, runners or deployments change.
  • Do not return proxy configuration to browser clients.
  • Use the authentication guide to choose password or IP allowlisting.

For API-focused workflows, continue with Proxies for API Testing. For browser execution, use the dedicated Playwright or Puppeteer guides rather than forcing a server-side HTTP agent into a browser process.

Choose the Node.js proxy method by runtime and HTTP client

There is no single proxy switch that automatically controls every Node.js networking library. Start with the runtime version and the client that actually sends the request. Newer Node releases can apply environment proxy settings to the built-in HTTP stack when the feature is enabled, while Undici offers an environment-aware dispatcher. Axios has its own request configuration, and a third-party SDK may wrap another transport entirely. Confirm the library path instead of assuming that an exported variable was consumed.

For a new service, centralize outbound HTTP creation in one module. That module can select the dispatcher or agent, apply timeouts, enforce redaction and expose a small health-check function. Business code then asks for an approved client rather than creating ad hoc Axios or fetch instances. This prevents one endpoint from silently bypassing the proxy after a dependency upgrade.

Verify behavior with a small compatibility test

Run the same three checks in development and deployment: an external IP request, an HTTPS request to a representative API and a request to a host covered by NO_PROXY. The first should show the proxy exit, the second confirms CONNECT and TLS behavior, and the third proves that exclusions work. Record the Node version and package lock revision with the result because proxy semantics can change across runtime and client versions.

Reuse connections without mixing proxy identities

Connection pooling improves performance, but the pool belongs to a route. Do not reuse one agent indiscriminately after changing proxy credentials or session identifiers. Maintain a bounded agent per proxy assignment, close idle agents and cap concurrent sockets. For scraping or regional API checks, keep one logical identity for a complete job and rotate between jobs, not between dependent requests.

Build useful error categories

Normalize low-level errors into a small operational vocabulary: DNS resolution, proxy connection, proxy authentication, tunnel establishment, TLS, upstream timeout and target HTTP response. Preserve the original error as structured metadata while keeping secrets out of logs. That distinction matters because retrying a 407 with the same credentials is wasteful, while retrying a transient connection reset on a different verified proxy may be reasonable.

When migrating an existing codebase, change one HTTP client at a time and compare direct and proxied integration tests. Keep a rollback switch, document the supported environment variables and link the service runbook to the proxy error guide. A controlled migration is more reliable than setting HTTP_PROXY globally and hoping every dependency interprets it the same way.

Node.js proxy FAQ

Does Node.js fetch support HTTP_PROXY?

Current supported Node releases can use built-in environment proxy support when explicitly enabled. Check the runtime version and current Node documentation.

What is EnvHttpProxyAgent?

It is an Undici dispatcher that reads HTTP_PROXY, HTTPS_PROXY and NO_PROXY variables and routes supported requests accordingly.

Can Axios use a proxy?

Yes. In Node.js, Axios has request configuration for HTTP proxy host, port and authentication. SOCKS commonly needs a compatible custom agent.

Why is NO_PROXY important?

It defines destinations that bypass the proxy. Incorrect patterns can cause accidental direct traffic or send internal requests through an external route.

Should I set a global dispatcher and Axios proxy together?

Avoid overlapping mechanisms unless the precedence is deliberately tested. Choose one owner for routing in each code path.

How do I test the Node.js proxy route?

Request a controlled IP endpoint with a timeout, compare the observed exit with the assigned proxy, then test the authorized target and classify any failure.

Use tested proxies in reproducible developer workflows

Use one explicit routing owner per client, protect credentials, close agents cleanly and size proxy concurrency from real valid requests.

Scroll to Top