netbirdio/netbird · error
failed reading access token response body with error: %v
Error message
failed reading access token response body with error: %v
What it means
Raised by DeviceAuthorizationFlow.requestToken when io.ReadAll fails while streaming the response body from the IdP token endpoint (client/internal/auth/device_flow.go:231-233). The HTTP request itself succeeded (headers received via d.HTTPClient.Do, a client with a 10s timeout), but the connection broke or timed out mid-body. This is a transport-level read failure, not an OAuth protocol error.
Source
Thrown at client/internal/auth/device_flow.go:233
return TokenRequestResponse{}, fmt.Errorf("failed to create request access token: %v", err)
}
req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
res, err := d.HTTPClient.Do(req)
if err != nil {
return TokenRequestResponse{}, fmt.Errorf("failed to request access token with error: %v", err)
}
defer func() {
err := res.Body.Close()
if err != nil {
return
}
}()
body, err := io.ReadAll(res.Body)
if err != nil {
return TokenRequestResponse{}, fmt.Errorf("failed reading access token response body with error: %v", err)
}
if res.StatusCode > 499 {
return TokenRequestResponse{}, fmt.Errorf("access token response returned code: %s", string(body))
}
tokenResponse := TokenRequestResponse{}
err = json.Unmarshal(body, &tokenResponse)
if err != nil {
return TokenRequestResponse{}, fmt.Errorf("parsing token response failed with error: %v", err)
}
return tokenResponse, nil
}
// WaitToken waits user's login and authorize the app. Once the user's authorize
// it retrieves the access token from Hosted's endpoint and validates it before returning.
// The method creates a timeout context internally based on info.ExpiresIn.View on GitHub (pinned to 93e97f4bf1)
Solutions
- Retry the login (netbird up) - transient connection resets resolve themselves on a fresh flow
- Check network stability between the client and the IdP token endpoint (curl -v the TokenEndpoint URL)
- If behind a proxy or TLS inspection appliance, bypass the IdP domain or install the inspection root CA on the host
- If the IdP is consistently slow, the 10s http.Client timeout in NewDeviceAuthorizationFlow may need raising (requires a client rebuild)
Example fix
// before (device_flow.go NewDeviceAuthorizationFlow)
httpClient := &http.Client{
Timeout: 10 * time.Second,
Transport: httpTransport,
}
// after - tolerate slow IdPs while still bounding the request
httpClient := &http.Client{
Timeout: 30 * time.Second,
Transport: httpTransport,
} Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight the token endpoint before starting a device flow
func tokenEndpointReachable(endpoint string) error {
req, err := http.NewRequest(http.MethodPost, endpoint, strings.NewReader(""))
if err != nil {
return err
}
client := &http.Client{Timeout: 10 * time.Second}
res, err := client.Do(req)
if err != nil {
return fmt.Errorf("token endpoint unreachable: %w", err)
}
defer res.Body.Close()
return nil
} Try / catch
flow, err := oauthFlow.WaitToken(ctx, info)
if err != nil {
if strings.Contains(err.Error(), "failed reading access token response body") {
// transport-level read failure: safe to restart the whole flow
log.Warnf("token body read failed, retrying login: %v", err)
return retryLogin(ctx)
}
return err
} Prevention
- Keep the network path between client and IdP free of truncating proxies and TLS-inspection middleboxes
- Pre-flight the token endpoint with a cheap POST before launching the interactive flow
- Surface the wrapped %v cause - it distinguishes timeouts from connection resets
When it happens
Trigger: POST to providerConfig.TokenEndpoint (grant_type urn:ietf:params:oauth:grant-type:device_code) succeeds at the TCP/TLS level, then the body read fails: connection reset by the IdP or an intermediate proxy, response body larger/slower than the http.Client 10s Timeout, or a TLS-inspecting middlebox truncating the response.
Common situations: Corporate proxies or SSL-inspection appliances cutting long responses, IdP load balancers dropping connections, flaky Wi-Fi/VPN on the user machine, or a slow IdP that exceeds the hard-coded 10-second client timeout while streaming the token payload.
Related errors
- access token response returned code: %s
- parsing token response failed with error: %v
- PKCE authorization flow failed: %v
- WebSocket connection timeout
- upload debug bundle: %w
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/f289eeb787d374ca.
Report an issue: GitHub.