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.OverTLSPublicKeyResponseView on GitHub (pinned to 5201273aec)
Solutions
- Retry the operation; transient mid-body failures usually succeed on a fresh connection
- Check for MTU or VPN tunnel issues if it recurs
- 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
- Treat mid-body read errors as transient by default
- Use reasonable per-request timeouts so stuck body reads surface fast
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
- all connection attempts failed (HTTP: %v, HTTPS: %v)
- failed to fetch next SSH action
- fetch control key: %v
- errHTTPPostFailure
- errNotUsingTailscale
AI-assisted analysis of tailscale/tailscale@5201273aec (2026-08-18).
Data as JSON: /api/errors/861531dbcb390b32.
Report an issue: GitHub.