Skip to content

NO_PROXY env var disables configured proxies globally #425

Open

Description

@AlecJY

When HTTPS_PROXY is configured, setting NO_PROXY for specific hosts makes PyManager bypass the proxy for every request. This breaks downloads in networks that require a proxy.

The problematic check is:

def _proxy_settings_from_env():
if os.getenv("NO_PROXY"):
return _ProxySettings(mode=PROXY_MODE_DIRECT)

NO_PROXY should bypass the proxy only for matching destinations, commonly local or private network addresses; other requests should continue using the configured proxy.

Activity

  1. zooba commented on Oct 12, 2026

    @zooba
    Member

    Since it's already an override for your system settings, I'm going to label this as a potential enhancement, not a bug. We assume that the system settings are global and the environment variables are local overrides, set specifically for running the install manager, and so you shouldn't need to override your own custom configuration (just fix the configuration).

    But if it's possible to flow through a per-destination proxy setting, then we can do it. Since we mostly outsource redirect handling to the OS though, I suspect it'll have limitations.

  2. Tinister commented on Oct 12, 2026

    @Tinister

    I'm in a corporate environment that sets HTTP_PROXY / HTTPS_PROXY / NO_PROXY for me, so it's not being used as a local override.

    The NO_PROXY behavior @AlecJY describes is a convention probably originating from curl, whereas pymanager seems to be just using it as an override flag. I expect not following convention is going to continue to cause headaches.

    If you do nothing else, at least drop support for NO_PROXY.

  3. zooba commented on Oct 13, 2026

    @zooba
    Member

    I expect not following convention is going to continue to cause headaches.

    Well, apparently following a convention is also causing headaches. There's a reason I left these out in the initial design and only added them because someone contributed it 😉

    Probably the best option here would be to switch the three variables into configuration settings that default to the variables (essentially, "NO_PROXY": "%NO_PROXY%" in the pymanager.json for each). Then you could define your own config file to override them and make them blank, so the variable is ignored. Would that be a workable approach?

  4. zooba commented on Oct 13, 2026

    @zooba
    Member

    Also, how does curl work in your environment? Or do you all just work around it by using a different tool? (I'm trying to get a feel for how correct/incorrect your corporate environment setup is.)

  5. Tinister commented on Oct 13, 2026

    @Tinister

    Speaking strictly as somebody who is aware my environment has these variables, have already worked out how pymanager is interpreting these variables, and has the patience to fiddle with config files, that sounds like a workable approach to me.

  6. Tinister commented on Oct 13, 2026

    @Tinister

    Testing both these binaries: "C:\Windows\System32\curl.exe" (v 8.13.0, bundled with Windows), and "C:\Program Files\Git\mingw64\bin\curl.exe" (v 8.21.0, bundled with Git for Windows)

    And testing with these environment variables set: HTTP_PROXY, HTTPS_PROXY, NO_PROXY -- where NO_PROXY is set to "localhost,myemployername.com,127.0.0.1"

    • using curl on an external site (e.g. https://www.python.org/) works fine.
    • using curl on an intranet site (e.g. under "myemployername.com") also works fine.
    • if I override NO_PROXY such that it is only "localhost,127.0.0.1" (e.g. removing myemployername.com) using curl on an intranet site no longer works.
    • if I override NO_PROXY such that it is "localhost,127.0.0.1,python.org" using curl on that external site no longer works.

    What would you have expected to happen?

  7. zooba commented on Oct 13, 2026

    @zooba
    Member

    In that case, I'd expect what you set.

    But what if you also clear HTTP_PROXY and HTTPS_PROXY? In that case, on a properly configured Windows machine, I'd expect the OS settings to be followed and everything to work (assuming the OS settings are correct).

    If you can set/unset one of those variables, it's fair to assume you can do it for all of them.

    So what remains is that we need someone to define and defend1 a proper specification for how these variables are meant to actually work. And then implement it, test it, and support it.

    Footnotes

    1. Since last time we only required someone to define the spec, and now I'm left having to defend something that I don't use, know about, or frankly care to worry about. ↩

  8. AlecJY commented on Oct 16, 2026

    @AlecJY
    Author

    I work in IT at a company where internet access must go through a proxy, while access to internal company resources should bypass it.

    We set HTTP_PROXY and HTTPS_PROXY as system environment variables because some cross-platform tools do not use the Windows proxy settings. Examples in our environment include tools such as curl and pip.

    We also set NO_PROXY for internal destinations, including localhost. For example, some software uses gRPC for local IPC. gRPC may inherit HTTP_PROXY and HTTPS_PROXY, causing proxy traffic to be sent for requests to localhost and interfering with the IPC connection. To avoid this, we ask users to configure NO_PROXY=localhost,127.0.0.1,.mycompany.com.

    I understand that implementing NO_PROXY consistently across pymanager’s different HTTP backends may be difficult. However, NO_PROXY is commonly used alongside HTTP_PROXY and HTTPS_PROXY to bypass the proxy for selected destinations while continuing to use it for other traffic. Since pymanager will usually need the proxy for internet access, treating any non-empty NO_PROXY value as a global switch to direct connections makes this configuration difficult to use.

    If supporting destination-specific NO_PROXY behavior consistently across all of pymanager’s HTTP backends, in a way that matches the behavior users expect from clients such as curl, urllib, or requests, is not practical, could pymanager ignore NO_PROXY or use a pymanager-specific variable such as PYMANAGER_DISABLE_PROXY to explicitly request direct connections? Treating any non-empty NO_PROXY value as a global proxy-disable switch can conflict with common proxy configurations, where NO_PROXY is used to bypass the proxy only for matching destinations.

    Thanks for considering this.

  9. zooba commented on Oct 16, 2026

    @zooba
    Member

    Thanks for the detail, it's very helpful.

    Treating any non-empty NO_PROXY value as a global proxy-disable switch can conflict with common proxy configurations, where NO_PROXY is used to bypass the proxy only for matching destinations.

    This is probably the point we can most easily change. We can require NO_PROXY to be one of 1,1 y[es], t[rue] (and maybe *?), and ignore any other value. We'd have to do something similar if we parse the whole value.

    We can also add a configuration setting to ignore these environment variables entirely, and rely on the OS configuration. I like my earlier idea of making the configuration default to reading those variables and can be overridden (by a user or an admin) to read different ones/none, but that might just be the appeal of a unified system and having an extra setting to ignore the other settings might be easier - I'll have to think about that one.

    I don't really want more ways to set the same values, since the interactions can get confusing. Also haven't ruled out that handling the full NO_PROXY value might be viable, I just haven't looked into it yet. Hopefully we can pass the entire value into the OS and let it figure it out - there are way too many CVEs about apps not perfectly handling processing of these kinds of arbitrary settings, and I don't want to expose us to that kind of risk.

    Footnotes

    1. The complete value being "1", since a prefix match would match the common 127.0.0.1. ↩

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions