claude-code icon indicating copy to clipboard operation
claude-code copied to clipboard

[BUG] Claude Code on the Web .NET SDK binary downloads blocked by proxy even with "All domains" network access enabled

Open BrentRector opened this issue 5 months ago • 6 comments

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

BrentRector avatar Nov 18 '25 20:11 BrentRector

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.

dwymark avatar Nov 18 '25 21:11 dwymark

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'."

JayVDZ avatar Nov 27 '25 09:11 JayVDZ

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/

WeihanLi avatar Dec 06 '25 11:12 WeihanLi

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.

gte619n avatar Dec 06 '25 16:12 gte619n

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 ==="

zkdiff avatar Dec 06 '25 23:12 zkdiff