bytebase/bytebase · error

failed to read body

Error message

failed to read body

What it means

fetchOpenIDConfiguration downloads the OIDC provider's discovery document (.well-known/openid-configuration). This error is thrown when io.ReadAll fails while draining the response body, typically because the connection was reset or timed out mid-transfer. It wraps the underlying I/O error so the root cause is preserved in the message chain.

Source

Thrown at backend/plugin/idp/oidc/oidc.go:282

	client := &http.Client{
		// Reached before authentication through GetAuthenticationInfo, which the
		// dashboard awaits before it mounts, so a blackholing issuer must not
		// hold a page load open for long.
		Timeout: 3 * time.Second,
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: insecureSkipVerify,
			},
		},
	}
	resp, err := client.Do(req)
	if err != nil {
		return nil, errors.Wrap(err, "fetch openid configuration")
	}

	b, err := io.ReadAll(resp.Body)
	if err != nil {
		return nil, errors.Wrapf(err, "failed to read body")
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return nil, errors.Errorf("received non-200 response code, code: %d, body: %s", resp.StatusCode, string(b))
	}

	var config OpenIDConfigurationResponse
	if err := json.Unmarshal(b, &config); err != nil {
		return nil, errors.Wrapf(err, "unmarshal openid configuration, body: %s", string(b))
	}
	return &config, nil
}

View on GitHub (pinned to 1870550677)

Solutions

  1. Retry the fetch — transient connection resets usually resolve on a second attempt.
  2. Check network connectivity and any proxy/firewall between Bytebase and the OIDC provider's issuer URL.
  3. Inspect the wrapped root-cause error for timeouts and increase the HTTP client timeout if it is too small.
  4. Verify the provider endpoint is healthy by fetching the discovery URL with curl.

Example fix

// before
b, err := io.ReadAll(resp.Body)
if err != nil {
    return nil, errors.Wrapf(err, "failed to read body")
}
// after
b, err := io.ReadAll(io.LimitReader(resp.Body, maxConfigSize))
if err != nil {
    return nil, errors.Wrapf(err, "failed to read body from %s", discoveryURL)
}
Defensive patterns

Strategy: retry

Validate before calling

null

Type guard

null

Try / catch

if err != nil {
    var netErr net.Error
    if errors.As(err, &netErr) && netErr.Timeout() {
        // backoff and retry the fetch
    }
    return fmt.Errorf("oidc discovery fetch failed: %w", err)
}

Prevention

When it happens

Trigger: Calling fetchOpenIDConfiguration when the HTTP server closes the connection or the connection drops while streaming the discovery document body, e.g. resp.Body read interrupted after headers were received.

Common situations: Provider behind a load balancer with aggressive idle timeouts; TLS termination proxy cutting the response short; network blips between the Bytebase server and the identity provider; provider sending Content-Length larger than what it sends before closing.

Related errors


AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06). Data as JSON: /api/errors/a91503ba049a627e. Report an issue: GitHub.