golang/go · error

network disabled by %v=%v

Error message

network disabled by %v=%v

What it means

Returned by AcquireNet() when the GODEBUG-controlled network limit (NetLimitGodebug) is set to 0, which disables all network access by the go command. The go command funnels every network operation (module/proxy fetches, VCS traffic) through a single semaphore (netLimitSem); a zero cap means no token can ever be acquired. This is an intentional kill-switch for offline/air-gapped builds, surfaced as a hard error so callers stop before touching the network.

Source

Thrown at src/cmd/go/internal/base/limit.go:48

		if err != nil {
			Fatalf("invalid %s: %v", NetLimitGodebug.Name(), err)
		}
		if n < 0 {
			// Treat negative values as unlimited.
			return
		}
		netLimitSem = make(chan struct{}, n)
	})

	return cap(netLimitSem), netLimitSem != nil
}

// AcquireNet acquires a semaphore token for a network operation.
func AcquireNet() (release func(), err error) {
	hasToken := false
	if n, ok := NetLimit(); ok {
		if n == 0 {
			return nil, fmt.Errorf("network disabled by %v=%v", NetLimitGodebug.Name(), NetLimitGodebug.Value())
		}
		netLimitSem <- struct{}{}
		hasToken = true
	}

	checker := new(netTokenChecker)
	cleanup := runtime.AddCleanup(checker, func(_ int) { panic("internal error: net token acquired but not released") }, 0)

	return func() {
		if checker.released {
			panic("internal error: net token released twice")
		}
		checker.released = true
		if hasToken {
			<-netLimitSem
		}
		cleanup.Stop()

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Unset or raise the GODEBUG net-limit setting so NetLimit() returns a positive value (remove the =0 token from $GODEBUG).
  2. If network must stay off, run with a vendor directory (GOFLAGS=-mod=vendor) so no AcquireNet path is hit.
  3. If the limit is being set unintentionally, inspect `go env GODEBUG` and your shell/toolchain config to find the source.
  4. For programmatic callers, call base.NetLimit() first and skip the network path when ok && n==0 instead of erroring.

Example fix

// before: network op attempted with GODEBUG net limit = 0
//   -> error: network disabled by <godebug>=0
//
// after: drop the net-limit override from GODEBUG
$ GODEBUG=$(echo "$GODEBUG" | tr , '\n' | grep -v '^netlimit=0$' | paste -sd,) go mod download
Defensive patterns

Strategy: validation

Validate before calling

if n, ok := base.NetLimit(); ok && n == 0 {
    // network is disabled by GODEBUG; skip the network path
    return ErrOffline
}
release, err := base.AcquireNet()

Prevention

When it happens

Trigger: Calling base.AcquireNet() while the effective GODEBUG net-limit setting resolves to 0 (the limit is configured via NetLimitGodebug, e.g. GODEBUG=...=0). Any go command path that reaches a network operation (go get, module download, VCS sync) will trip it.

Common situations: Reproducible/offline CI that pins GODEBUG to disable network; sandboxed build environments; users who copied a GODEBUG value from a hardening guide without understanding the net limit; GOPROXY=off builds that also set the limit.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/042a0a28165d1809. Report an issue: GitHub.