tailscale/tailscale · error

fetch control key response: %v

Error message

fetch control key response: %v

What it means

The response headers for GET /key arrived, but reading the body with io.ReadAll(io.LimitReader(res.Body, 64<<10)) failed. The connection dropped between headers and body completion (read error, reset, timeout).

Source

Thrown at control/controlclient/direct.go:1498

	return nil
}

// encode JSON encodes v as JSON, logging tailcfg.MapRequest values if
// debugMap is set.
func encode(v any) ([]byte, error) {
	b, err := json.Marshal(v)
	if err != nil {
		return nil, err
	}
	if DevKnob.DumpNetMaps() {
		if _, ok := v.(*tailcfg.MapRequest); ok {
			log.Printf("MapRequest: %s", b)
		}
	}
	return b, nil
}

func loadServerPubKeys(ctx context.Context, httpc *http.Client, serverURL string) (*tailcfg.OverTLSPublicKeyResponse, error) {
	keyURL := fmt.Sprintf("%v/key?v=%d", serverURL, tailcfg.CurrentCapabilityVersion)
	req, err := http.NewRequestWithContext(ctx, "GET", keyURL, nil)
	if err != nil {
		return nil, fmt.Errorf("create control key request: %v", err)
	}
	res, err := httpc.Do(req)
	if err != nil {
		return nil, fmt.Errorf("fetch control key: %v", err)
	}
	defer res.Body.Close()
	b, err := io.ReadAll(io.LimitReader(res.Body, 64<<10))
	if err != nil {
		return nil, fmt.Errorf("fetch control key response: %v", err)
	}
	if res.StatusCode != 200 {
		return nil, fmt.Errorf("fetch control key: %v", res.Status)
	}
	var out tailcfg.OverTLSPublicKeyResponse

View on GitHub (pinned to 5201273aec)

Solutions

  1. Retry the operation; transient mid-body failures usually succeed on a fresh connection
  2. Check for MTU or VPN tunnel issues if it recurs
  3. Reproduce with curl to see whether the server consistently truncates the /key response
Defensive patterns

Strategy: retry

Try / catch

var netErr net.Error
if errors.As(err, &netErr) {
    // transient read failure: retry on a fresh connection with backoff
}

Prevention

When it happens

Trigger: Connection reset mid-body by a proxy or load balancer, read timeout expiring while streaming the key response, or a TLS error surfacing during body read.

Common situations: Flaky networks (Wi-Fi/VPN transitions), proxies that close connections early after headers, servers that close keep-alive connections abruptly.

Related errors


AI-assisted analysis of tailscale/tailscale@5201273aec (2026-08-18). Data as JSON: /api/errors/861531dbcb390b32. Report an issue: GitHub.