nodejs / nodejs/node

NO_PROXY=example.com does not bypass subdomains for http.request(), unlike fetch()

Open
#65,616 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
122k
Forks
37.3k
Avg merge
4d 2h
Merged PRs (30d)
283

Description

Version

v24.18.1, also on main (v27.0.0-pre)

Platform
Darwin xxx.local 25.3.0 Darwin Kernel Version 25.3.0: Wed Jan 28 20:54:46 PST 2026; root:xnu-12377.91.3~2/RELEASE_ARM64_T6000 arm64
Subsystem

http

What steps will reproduce the bug?

Dead proxy on port 1 — the error code shows where the request went:

NODE_USE_ENV_PROXY=1 HTTP_PROXY=http://127.0.0.1:1 NO_PROXY=example.com node repro.js
const http = require('node:http');

http.get('http://internal.example.com/').on('error', (e) => console.log(e.cause?.code ?? e.code));
// ECONNREFUSED — went through the proxy

fetch('http://internal.example.com/').catch((e) => console.log(e.cause?.code ?? e.code));
// ENOTFOUND — bypassed, hit DNS
How often does it reproduce? Is there a required condition?

Always, when the NO_PROXY entry has no leading dot and the request host is a subdomain of that entry.

What is the expected behavior? Why is that the expected behavior?

Same NO_PROXY in the same process should mean the same thing for http.request() / http.get() and fetch(). http.setGlobalProxyFromEnv() and the docs present one NO_PROXY format for both.

fetch() (undici EnvHttpProxyAgent) already treats a plain example.com as the host and its subdomains, with a label boundary so notexample.com does not match. http should do the same.

What do you see instead?

ProxyConfig#shouldUseProxy exact-matches a plain entry against the hostname. NO_PROXY=example.com therefore does not bypass internal.example.com for http.request(), while fetch() does.

The docs currently describe this as “Exact host name match”, which matches the http implementation and not fetch().

Additional information

Refs: #57872, #62907

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the repro.js behavior and the http entry point ProxyConfig#shouldUseProxy; compare it with fetch()'s EnvHttpProxyAgent and the NO_PROXY documentation. Done means a plain example.com entry bypasses its subdomains with a label boundary, while http.request() and fetch() agree.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, nodejs
Domain
backend, networking
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.