ory/kratos · error
failed to initialize provider
Error message
failed to initialize provider
What it means
discoverPKCE calls gooidc.NewProvider against the OIDC provider's Issuer URL to fetch its discovery document and check PKCE support. This error wraps any failure of that OIDC discovery request (DNS failure, TLS error, non-200 discovery response, malformed discovery JSON). It means the issuer could not be reached or did not return a valid OpenID Connect discovery document.
Solutions
- Verify the provider's issuer_url in the OIDC config matches exactly what the OP advertises (scheme, host, path) and is reachable via GET <issuer>/.well-known/openid-configuration.
- Test with curl from the same host to rule out network/DNS/proxy issues.
- If using self-signed TLS, ensure the HTTP client used (d.HTTPClient(ctx)) trusts the OP's CA.
- Inspect the wrapped cause (errors.Cause / %v of err) for the specific discovery failure.
Example fix
// before: issuer_url: "https://op.example.com/.well-known/openid-configuration" // after: issuer_url: "https://op.example.com" (bare issuer, library appends the well-known path)
Defensive patterns
Strategy: try-catch
Validate before calling
resp, err := http.Get(issuerURL + "/.well-known/openid-configuration")
if err != nil || resp.StatusCode != 200 { /* fail fast before PKCE discovery */ } Try / catch
if _, err := discoverPKCE(ctx, p); err != nil {
if cause := errors.Cause(err); cause != nil {
log.WithError(cause).Error("OIDC discovery failed")
}
return fallbackPKCE // e.g. treat as no PKCE support or fail startup with clear config error
} Prevention
- Configure the bare issuer URL (no /.well-known path).
- Verify issuer reachability from the deployment environment at startup.
- Trust the OP's TLS CA in the HTTP client used for discovery.
When it happens
Trigger: Calling maybePKCE/discoverPKCE when the provider has an IssuerURL set but gooidc.NewProvider(ctx, issuerURL) fails: issuer URL unreachable, wrong issuer path, discovery document returning HTTP error, or discovery JSON not matching the well-known schema.
Common situations: Misconfigured issuer URL (e.g. missing https://, wrong path, includes the well-known suffix), OP temporarily down or behind a firewall, self-signed certificates without proper CA trust, or the issuer metadata not matching the URL exactly (strict issuer validation in go-oidc).
Understand the failure class
Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.
Related errors
- failed to deserialize provider claims
- Private key decoding failed
- provider type is not supported, supported are
- no credentials found
- Issuer URL must be set to autodiscover PKCE support
AI-assisted analysis of ory/kratos@b86338da04 (2026-09-07).
Data as JSON: /api/errors/62254be169d1bd8f.
Report an issue: GitHub.
Appendix: source
Thrown at selfservice/strategy/oidc/pkce.go:71
return ""
}
if !pkceSupported {
d.Logger().Infof("Provider %q does not advertise support for PKCE. Continuing without PKCE.", p.Config().ID)
return ""
}
}
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)