microsoft / microsoft/WSL

wslc pull (and WSL autoProxy) fail behind a PAC/Zscaler proxy: http_proxy is set but HTTPS_PROXY is left empty, so HTTPS registry pulls bypass the proxy and time out

Open
#40,945 3 comments 4 reactions 0 assignees View on GitHub
feature wslc
Dominant language
C++
Stars
33.7k
Forks
1.8k
Avg merge
3d 17h
Merged PRs (30d)
116

Description

### Windows Version

Microsoft Windows [Version 10.0.26200.8655]

### WSL Version

2.9.3.0

### Are you using WSL 1 or WSL 2?

- [x] WSL 2
- [ ] WSL 1

### Kernel Version

_No response_

### Distro Version

Oracle Linux 9

### Other Software

On a machine whose only proxy configuration is a PAC script (AutoConfigURL), wslc pull of any HTTPS registry image times out:

wslc pull container-registry.oracle.com/os/oraclelinux:9
Get "https://container-registry.oracle.com/v2/": net/http: request canceled
while waiting for connection (Client.Timeout exceeded while awaiting headers)
context deadline exceeded
Error code: E_FAIL

curl -x http://:443 https://container-registry.oracle.com/v2/ → HTTP 401 (expected auth challenge = connectivity OK)

Root cause (from source, 2.9.3 tree)

In src/windows/service/exe/LxssUserSession.cpp, http_proxy/HTTP_PROXY are always injected, but https_proxy/HTTPS_PROXY are only injected when SecureProxy is non-empty:

http_proxy / HTTP_PROXY = proxySettings.Proxy // ALWAYS set
if (!proxySettings.SecureProxy.empty()) { // CONDITIONAL
https_proxy / HTTPS_PROXY = proxySettings.SecureProxy
}

In src/windows/service/exe/LxssHttpProxy.cpp:
Proxy = WideToMultiByte(WINHTTP_PROXY_SETTINGS_EX.pcwszProxy);
SecureProxy = WideToMultiByte(WINHTTP_PROXY_SETTINGS_EX.pcwszSecureProxy);

When proxy config comes from a PAC, WinHTTP returns a populated pcwszProxy but an empty pcwszSecureProxy. Result: WSL injects only http_proxy and leaves HTTPS_PROXY empty. Since registry pulls are HTTPS, the request goes direct to :443, has no route out of the corporate network, and times out.

Two distinct problems
autoProxy / PAC handling (general WSL): with a PAC-only config, HTTPS_PROXY is never set. Reproducible in the default distro — autoProxy injects http_proxy=http://:443 but HTTPS_PROXY is empty.
WSLC backend session is hermetic (WSLC-specific): the WSLC backend session VM receives no proxy environment at all — wslc system session run env returns only:

PATH=/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/sbin

It gets neither http_proxy nor HTTPS_PROXY, even though the default distro at least gets http_proxy. So even the autoProxy http_proxy doesn't reach where the pull actually runs.

What does NOT work (verified)

.wslconfig autoProxy=true + networkingMode=mirrored — still only http_proxy.
Setting $env:HTTPS_PROXY / machine HTTPS_PROXY before wslc pull — backend ignores Windows env.
WSLENV=HTTP_PROXY/u:HTTPS_PROXY/u:NO_PROXY/u — does not reach the WSLC session VM.
Terminating and recreating the WSLC session with proxy env set — fresh session still shows only PATH.
wslc pull has no proxy flag; settings.yaml has no proxy field; .wslconfig has no static-proxy-override key (only the autoProxy boolean + initialAutoProxyTimeout).
Suggested fixes

Suggested fixes
Fall back Proxy → SecureProxy when SecureProxy is empty (especially for PAC results), so HTTPS traffic uses the same proxy as HTTP. A PAC returning a single proxy almost always intends it for both schemes.
Propagate proxy env into the WSLC backend session VM (it currently gets none), or expose a proxy setting in settings.yaml / a --proxy flag on wslc pull/wslc load.

Workaround (for others hitting this)
Pull in a regular distro with proxy env set manually, then load into wslc:

# in OracleLinux_8_7 as root, with http_proxy/https_proxy exported
dnf -y install skopeo
skopeo copy --override-os linux \
docker://container-registry.oracle.com/os/oraclelinux:9 \
docker-archive:/mnt/c/tmp/ol9.tar:container-registry.oracle.com/os/oraclelinux:9

wslc load -i C:\tmp\ol9.tar
wslc run --rm container-registry.oracle.com/os/oraclelinux:9 cat /etc/oracle-release
# -> Oracle Linux Server release 9.8

### Repro Steps

setup autproxy to pac url
wslc pull container-registry.oracle.com/os/oraclelinux:9
Get "https://container-registry.oracle.com/v2/": net/http: request canceled
while waiting for connection (Client.Timeout exceeded while awaiting headers)
context deadline exceeded
Error code: E_FAIL

### Expected Behavior

it should be able to use proxy form the autopac url or provide explicit support for proxy flag to wslc.exe command line.

### Actual Behavior

Get "https://container-registry.oracle.com/v2/": net/http: request canceled
while waiting for connection (Client.Timeout exceeded while awaiting headers)
context deadline exceeded
Error code: E_FAIL

### Diagnostic Logs

_No response_

Contributor guide

Open the contributing guide

Research direction

Start with src/windows/service/exe/LxssUserSession.cpp and src/windows/service/exe/LxssHttpProxy.cpp, then reproduce the PAC setup with wslc pull and inspect the WSLC system session environment. Trace how Proxy and SecureProxy are populated and injected; done means HTTPS registry pulls through the PAC proxy and the WSLC backend receives the required proxy configuration.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
cli, networking, operating-systems
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.