chenhg5/cc-connect · error

providerproxy: listen: %w

Error message

providerproxy: listen: %w

What it means

After parsing the target, `NewProviderProxy` binds a local listener on `127.0.0.1:0` (an ephemeral port). If `net.Listen` fails it returns `providerproxy: listen: %w`. Binding to an OS-chosen port on loopback should virtually never fail; failure indicates a serious system-level networking problem.

Source

Thrown at core/providerproxy.go:44

	thinkingOverride string
	listener         net.Listener
	server           *http.Server
	once             sync.Once
}

// NewProviderProxy creates and starts a local reverse proxy for the
// given upstream URL. thinkingOverride controls what thinking.type to
// rewrite "adaptive" to (e.g. "disabled" or "enabled").
// Returns the local URL to use as ANTHROPIC_BASE_URL.
func NewProviderProxy(targetURL, thinkingOverride string) (*ProviderProxy, string, error) {
	target, err := url.Parse(strings.TrimRight(targetURL, "/"))
	if err != nil {
		return nil, "", fmt.Errorf("providerproxy: parse target: %w", err)
	}

	listener, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		return nil, "", fmt.Errorf("providerproxy: listen: %w", err)
	}

	proxy := httputil.NewSingleHostReverseProxy(target)
	origDirector := proxy.Director
	proxy.Director = func(req *http.Request) {
		origDirector(req)
		req.Host = target.Host
	}
	proxy.FlushInterval = -1 // flush SSE events immediately

	override := thinkingOverride
	mux := http.NewServeMux()
	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		if r.Method == http.MethodPost && strings.HasSuffix(r.URL.Path, "/messages") {
			rewriteThinkingInRequest(r, override)
		}
		proxy.ServeHTTP(w, r)
	})

View on GitHub (pinned to 4000b2338a)

Solutions

  1. Check the underlying wrapped error; `EMFILE`/`ENFILE` means raise the file-descriptor limit (`ulimit -n`).
  2. If running in a sandbox/container, grant permission to create TCP sockets on loopback.
  3. Audit for socket/fd leaks in the process (`lsof -p <pid>`) and fix the leak.
  4. Retry after other connections close if the port range is temporarily exhausted.
Defensive patterns

Strategy: try-catch

Try / catch

proxy, local, err := NewProviderProxy(target, thinking)
if err != nil {
    slog.Error("provider proxy start failed", "error", err) // inspect wrapped net.OpError (EMFILE, EPERM, ...)
    return err
}

Prevention

When it happens

Trigger: Calling NewProviderProxy when the OS refuses to open a loopback TCP socket: exhausted ephemeral port range / file-descriptor limit, socket creation denied by sandbox/seccomp policy, or networking stack unavailable.

Common situations: Container with a very low RLIMIT_NOFILE and thousands of open connections; hardened sandbox (gVisor, restricted Docker) forbidding socket creation; host with `net.ipv4.ip_local_port_range` exhausted by leaked sockets.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of chenhg5/cc-connect@4000b2338a (2026-09-06). Data as JSON: /api/errors/8e94a6bca66f22bb. Report an issue: GitHub.