ory/kratos · error
failed to deserialize provider claims
Error message
failed to deserialize provider claims
What it means
After a successful OIDC discovery, discoverPKCE extracts claims (notably code_challenge_methods_supported) from the provider metadata via gp.Claims(&claims). This error means the discovery document was fetched but its claims could not be deserialized into the expected struct — the JSON did not conform to expectations.
Solutions
- Fetch <issuer>/.well-known/openid-configuration with curl and validate it is well-formed JSON matching the OIDC Discovery spec.
- Check for a proxy or WAF rewriting the discovery response.
- Update the go-oidc library / Ory Kratos version in case of known claim-parsing incompatibilities.
- As a workaround, disable automatic PKCE autodiscovery for this provider and configure PKCE explicitly if the option exists.
Defensive patterns
Strategy: try-catch
Validate before calling
body, _ := io.ReadAll(resp.Body)
var raw map[string]any
if err := json.Unmarshal(body, &raw); err != nil { /* provider returned invalid discovery JSON */ } Try / catch
supported, err := discoverPKCE(ctx, p)
if err != nil {
log.WithError(err).Warn("PKCE autodiscovery failed; assuming S256")
supported = true // safe fallback: S256 is widely supported
} Prevention
- Validate the OP's discovery document against the OIDC Discovery spec once during setup.
- Watch for proxies that replace error pages for the well-known endpoint.
- Pin and update go-oidc versions to get claim-parsing fixes.
When it happens
Trigger: gp.Claims(&claims) fails during discoverPKCE because the discovery document returned by the OP contains code_challenge_methods_supported (or the overall metadata) in a shape that cannot unmarshal into the claims struct, or the response is malformed JSON.
Common situations: Non-compliant OIDC providers returning discovery metadata with unexpected types, proxies/HTML error pages served with 200 instead of the JSON document, or truncated responses.
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
- failed to initialize provider
- Issuer URL must be set to autodiscover PKCE support
- failed to decode PEM block containing private key
- Private key is not ecdsa key
- no oidc provider was set
AI-assisted analysis of ory/kratos@b86338da04 (2026-09-07).
Data as JSON: /api/errors/a7d309271ca7ba74.
Report an issue: GitHub.
Appendix: source
Thrown at selfservice/strategy/oidc/pkce.go:77
}
return oauth2.GenerateVerifier()
}
func discoverPKCE(ctx context.Context, d pkceDependencies, p OAuth2Provider) (pkceSupported bool, err error) {
if p.Config().IssuerURL == "" {
return false, errors.New("Issuer URL must be set to autodiscover PKCE support")
}
ctx = gooidc.ClientContext(ctx, d.HTTPClient(ctx).HTTPClient)
gp, err := gooidc.NewProvider(ctx, p.Config().IssuerURL)
if err != nil {
return false, errors.Wrap(err, "failed to initialize provider")
}
var claims struct {
CodeChallengeMethodsSupported []string `json:"code_challenge_methods_supported"`
}
if err := gp.Claims(&claims); err != nil {
return false, errors.Wrap(err, "failed to deserialize provider claims")
}
return slices.Contains(claims.CodeChallengeMethodsSupported, "S256"), nil
}
View on GitHub (pinned to b86338da04)