oauth2-proxy/oauth2-proxy · error
unable to unmarshal raw response body: %w
Error message
unable to unmarshal raw response body: %w
What it means
fetchToken parses the token endpoint's HTTP response body. It first unmarshals the body into a generic interface to keep the raw response (for oauth2 token extras). This error is thrown when the body is not valid JSON, wrapping the json.Unmarshal error.
Source
Thrown at providers/ms_entra_id.go:318
}
}
return false
}
func (p *MicrosoftEntraIDProvider) fetchToken(ctx context.Context, params url.Values) (*oauth2.Token, error) {
resp := requests.New(p.RedeemURL.String()).
WithContext(ctx).
WithMethod(http.MethodPost).
WithBody(bytes.NewBufferString(params.Encode())).
SetHeader("Content-Type", "application/x-www-form-urlencoded").
Do()
var token *oauth2.Token
var rawResponse interface{}
body := resp.Body()
if err := json.Unmarshal(body, &rawResponse); err != nil {
return nil, fmt.Errorf("unable to unmarshal raw response body: %w", err)
}
if err := json.Unmarshal(body, &token); err != nil {
return nil, fmt.Errorf("unable to unmarshal token response body: %w", err)
}
return token.WithExtra(rawResponse), nil
}
View on GitHub (pinned to 33c2eb92de)
Solutions
- Log the actual response body (the wrapped %w error includes the JSON syntax detail) to see what came back
- Check for a corporate proxy/WAF intercepting requests to login.microsoftonline.com and add an exception
- Verify the configured token endpoint URL points at the real OAuth2 token endpoint
- Retry — transient gateway errors can return truncated/empty bodies
Defensive patterns
Strategy: retry
Validate before calling
// preflight: check connectivity through your proxy to the token endpoint
req, _ := http.NewRequest("POST", tokenURL, nil)
resp, err := http.DefaultClient.Do(req)
if err == nil && strings.Contains(http.DetectContentType(peerBody(resp)), "text/html") {
log.Println("proxy/WAF returned HTML instead of JSON")
} Try / catch
if err := provider.RefreshSession(ctx, sess); err != nil {
if strings.Contains(err.Error(), "unable to unmarshal raw response body") {
// body wasn't JSON (proxy page, empty body): retry after backoff, then alert
}
} Prevention
- Exempt login.microsoftonline.com from corporate proxy/WAF interception
- Monitor for non-JSON responses from the token endpoint
- Use plain-text logging of response content-type on failures
- Retry transient gateway errors with backoff before surfacing to the user
When it happens
Trigger: fetchToken (called from redeemWithFederatedToken / redeemRefreshTokenWithFederatedToken) receives a response body that is not valid JSON: HTML error pages from proxies/gateways, empty bodies, or plain-text errors from Azure AD or an intercepting middlebox.
Common situations: Corporate proxy or WAF returning an HTML block page; Azure AD returning a non-JSON error; wrong token endpoint URL hitting a login page; TLS-terminating appliance injecting content.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- unable to unmarshal token response body: %w
- failed to parse default id_token claims: %v
- failed to parse ID Token payload: %w
- error making request to profile URL: %v
- error unmarshalling body: %v
AI-assisted analysis of oauth2-proxy/oauth2-proxy@33c2eb92de (2026-09-06).
Data as JSON: /api/errors/6fb7a721deabba7e.
Report an issue: GitHub.