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

  1. Retry the login (netbird up) - transient connection resets resolve themselves on a fresh flow
  2. Check network stability between the client and the IdP token endpoint (curl -v the TokenEndpoint URL)
  3. If behind a proxy or TLS inspection appliance, bypass the IdP domain or install the inspection root CA on the host
  4. 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

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


AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16). Data as JSON: /api/errors/f289eeb787d374ca. Report an issue: GitHub.