[BUG] Claude Code on the Web .NET SDK binary downloads blocked by proxy even with "All domains" network access enabled
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Claude Code on the Web. When network egress is configured with "All domains" allowed, the Claude Code sandbox proxy still blocks downloads of .NET SDK binaries from Microsoft's CDN servers, returning "Access denied" (403 Forbidden).
This prevents compilation of .NET 9.x projects within Claude Code sessions, requiring users to manually compile code on their end and report errors back to Claude.
Environment Platform: Ubuntu 24.04.3 LTS (x86_64) Network Setting: "All domains" enabled .NET 8.0 available via apt (works) .NET 9.0 requires binary download (blocked) Blocked Domains All Microsoft .NET binary download servers return 403:
builds.dotnet.microsoft.com ci.dot.net dotnetcli.azureedge.net download.visualstudio.microsoft.com dotnet.microsoft.com aka.ms (redirects to above) Reproduction Steps
This works - GitHub raw content
curl -sSL https://raw.githubusercontent.com/dotnet/install-scripts/main/src/dotnet-install.sh -o /tmp/install.sh
Returns: valid 1888-line shell script
Workaround None currently. Users must:
Have Claude write code Pull and compile locally Report errors back to Claude Repeat until code compiles This significantly reduces productivity for .NET development.
Impact Cannot compile .NET 9.x projects Cannot run tests Cannot validate syntax before committing Increased back-and-forth between user and Claude
What Should Happen?
Claude should allow installation of the .NET 9.x SDK. Ideally it should be installed by default.
Error Messages/Logs
Steps to Reproduce
This fails - Microsoft CDN
curl -sSL https://dotnetcli.azureedge.net/dotnet/Sdk/9.0.101/dotnet-sdk-9.0.101-linux-x64.tar.gz
Returns: "Access denied" (13 bytes)
Install script fails
/tmp/install.sh --channel 9.0 --install-dir $HOME/.dotnet
Error: 403 Unable to download
Expected Behavior With "All domains" network access enabled, .NET SDK binaries should be downloadable from Microsoft CDN servers.
Claude Model
Sonnet (default)
Is this a regression?
No, this never worked
Last Working Version
No response
Claude Code Version
Claude Code on the Web
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
Other
Additional Information
No response
Maybe related: git push is failing for me on Claude Code web as of about an hour ago and will not work for any sessions. Similar proxy errors are printed.
This also affects dotnet restore as NuGet package endpoints are blocked, making Claude Code unusable for Dotnet coding.
The build environment has network restrictions that prevent local build/test verification: when attempting to restore NuGet packages, requests to api.nuget.org are routed through a proxy server at http://21.0.0.139:15004/ which returns 401 Unauthorized (missing proxy credentials), and when attempting to bypass the proxy entirely by clearing proxy environment variables, direct HTTPS connections to NuGet fail with "Resource temporarily unavailable" indicating outbound HTTPS is blocked without the proxy.
This creates a catch-22 where NuGet package restoration is impossible locally - the proxy requires authentication credentials we don't have, and direct access is blocked by network policy.
Raw log example:
Determining projects to restore...
Restored /home/user/JIM/JIM.Functions/JIM.Functions.csproj (in 505 ms).
/home/user/JIM/JIM.Utilities/JIM.Utilities.csproj : error NU1301: Unable to load the service index for source https://api.nuget.org/v3/index.json. [/home/user/JIM/JIM.sln]
/home/user/JIM/JIM.Utilities/JIM.Utilities.csproj : error NU1301: The proxy tunnel request to proxy 'http://21.0.0.139:15004/' failed with status code '401'."
Seems obsolete url used, the CDN used already moved to new url builds.dotnet.microsoft.com
https://devblogs.microsoft.com/dotnet/critical-dotnet-install-links-are-changing/
This makes grade/maven unusable in Java builds as well. This would be a huge fix to allow unit tests to run in Claude Code before digging in manually.
I'm sure there are better options than this workaround but it gets dotnet restore to work for me. I'll try to circle back and look into this more if I get a chance—in the meantime:
#!/usr/bin/env bash
set -e
SOLUTION_PATH="${1:-.}"
DOTNET_VERSION="${2:-10.0}"
LOCAL_PROXY_PORT=18080
echo "=== Installing .NET SDK $DOTNET_VERSION ==="
curl -fsSL https://dot.net/v1/dotnet-install.sh | bash -s -- --channel "$DOTNET_VERSION"
export PATH="$HOME/.dotnet:$PATH"
dotnet --version
echo "=== Creating proxy relay script ==="
cat > /tmp/proxy_relay.py << 'EOF'
#!/usr/bin/env python3
import os, socket, threading, base64
from urllib.parse import urlparse
upstream_url = os.environ.get('HTTPS_PROXY', '')
parsed = urlparse(upstream_url)
UPSTREAM_HOST = parsed.hostname
UPSTREAM_PORT = parsed.port or 8080
PROXY_USER = parsed.username or ''
PROXY_PASS = parsed.password or ''
auth_b64 = base64.b64encode(f"{PROXY_USER}:{PROXY_PASS}".encode()).decode()
LOCAL_PORT = int(os.environ.get('LOCAL_PROXY_PORT', 18080))
def handle_client(client_socket):
try:
request = client_socket.recv(65536)
if not request:
client_socket.close()
return
upstream_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
upstream_socket.connect((UPSTREAM_HOST, UPSTREAM_PORT))
lines = request.decode('utf-8', errors='ignore').split('\r\n')
new_lines = [lines[0], f"Proxy-Authorization: Basic {auth_b64}"] + lines[1:]
upstream_socket.send('\r\n'.join(new_lines).encode())
def forward(src, dst):
try:
while True:
data = src.recv(65536)
if not data:
break
dst.send(data)
except:
pass
finally:
src.close()
dst.close()
t1 = threading.Thread(target=forward, args=(upstream_socket, client_socket), daemon=True)
t2 = threading.Thread(target=forward, args=(client_socket, upstream_socket), daemon=True)
t1.start()
t2.start()
t1.join()
t2.join()
except Exception as e:
print(f"Error: {e}")
client_socket.close()
def main():
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server.bind(('127.0.0.1', LOCAL_PORT))
server.listen(100)
print(f"Proxy relay on 127.0.0.1:{LOCAL_PORT} -> {UPSTREAM_HOST}:{UPSTREAM_PORT}")
while True:
client_socket, _ = server.accept()
threading.Thread(target=handle_client, args=(client_socket,), daemon=True).start()
if __name__ == '__main__':
main()
EOF
echo "=== Starting proxy relay ==="
LOCAL_PROXY_PORT=$LOCAL_PROXY_PORT python3 /tmp/proxy_relay.py &
PROXY_PID=$!
sleep 2
if ! kill -0 $PROXY_PID 2>/dev/null; then
echo "ERROR: Proxy relay failed to start"
exit 1
fi
echo "Proxy relay running (PID: $PROXY_PID)"
# Kill proxy on script exit
trap 'kill $PROXY_PID 2>/dev/null' EXIT
echo "=== Running dotnet restore ==="
env -i PATH="$HOME/.dotnet:$PATH" \
HOME="$HOME" \
HTTPS_PROXY="http://127.0.0.1:$LOCAL_PROXY_PORT" \
HTTP_PROXY="http://127.0.0.1:$LOCAL_PROXY_PORT" \
dotnet restore "$SOLUTION_PATH"
echo "=== Done ==="