tailscale/tailscale · error
reading register response: %w
Error message
reading register response: %w
What it means
The 200 response body could not be read to completion: io.ReadAll over a LimitReader failed (control/tsp/register.go:103). The server accepted the request and began replying, then the stream broke: connection reset, TLS error, premature close, or context cancellation during the read.
Source
Thrown at control/tsp/register.go:103
res, err := nc.Do(req)
if err != nil {
return nil, fmt.Errorf("register request: %w", err)
}
defer res.Body.Close()
maxResponseSize := cmp.Or(opts.MaxResponseSize, DefaultMaxMessageSize)
if res.StatusCode != 200 {
msg, _ := io.ReadAll(io.LimitReader(res.Body, maxResponseSize))
return nil, fmt.Errorf("register request: http %d: %.200s",
res.StatusCode, strings.TrimSpace(string(msg)))
}
// Read up to maxResponseSize+1 so we can distinguish "exactly at cap" from
// "over the cap" rather than relying on a truncated json parse error.
data, err := io.ReadAll(io.LimitReader(res.Body, maxResponseSize+1))
if err != nil {
return nil, fmt.Errorf("reading register response: %w", err)
}
if int64(len(data)) > maxResponseSize {
return nil, fmt.Errorf("register response exceeds max %d", maxResponseSize)
}
var resp tailcfg.RegisterResponse
if err := json.Unmarshal(data, &resp); err != nil {
return nil, fmt.Errorf("decoding register response: %w", err)
}
if resp.Error != "" {
return nil, fmt.Errorf("register: %s", resp.Error)
}
return &resp, nil
}
View on GitHub (pinned to 6e0912f979)
Solutions
- Retry the call; usually transient
- If reproducible, correlate with server logs for a crash mid-response
- Raise read timeouts on slow links and on intermediaries
Defensive patterns
Strategy: retry
Try / catch
if err != nil {
if errors.Is(err, io.ErrUnexpectedEOF) || errors.Is(err, context.DeadlineExceeded) {
// mid-body break: safe to retry the whole request
resp, err = c.Register(ctx, opts)
}
} Prevention
- Set generous read timeouts when responses can be large
- Avoid cancelling the ctx while the response body is still streaming
When it happens
Trigger: Server closes the connection mid-response; proxy/LB idle timeout cutting the transfer; ctx canceled while the body streams.
Common situations: Flaky links; aggressive intermediary timeouts; control server crashing while building the registration response.
Related errors
- register request: %w
- fetching server key: %w
- errNotUsingTailscale
- tailscale version not found in output
- failed refresh apk repository indexes: %w, output: %s
AI-assisted analysis of tailscale/tailscale@6e0912f979 (2026-08-18).
Data as JSON: /api/errors/220e39b9dc42f299.
Report an issue: GitHub.