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

  1. 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.
  2. Test with curl from the same host to rule out network/DNS/proxy issues.
  3. If using self-signed TLS, ensure the HTTP client used (d.HTTPClient(ctx)) trusts the OP's CA.
  4. 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

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


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)