{"record":{"id":"03157df3d79b5bbf","repo":"ory/kratos","slug":"issuer-url-must-be-set-to-autodiscover-pkce-suppor","errorCode":null,"errorMessage":"Issuer URL must be set to autodiscover PKCE support","messagePattern":"Issuer URL must be set to autodiscover PKCE support","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"selfservice/strategy/oidc/pkce.go","lineNumber":65,"sourceCode":"\n\tif p.Config().PKCE != \"force\" {\n\t\t// autodiscover PKCE support\n\t\tpkceSupported, err := discoverPKCE(ctx, d, p)\n\t\tif err != nil {\n\t\t\td.Logger().WithError(err).Warnf(\"Failed to autodiscover PKCE support for provider %q. Continuing without PKCE.\", p.Config().ID)\n\t\t\treturn \"\"\n\t\t}\n\t\tif !pkceSupported {\n\t\t\td.Logger().Infof(\"Provider %q does not advertise support for PKCE. Continuing without PKCE.\", p.Config().ID)\n\t\t\treturn \"\"\n\t\t}\n\t}\n\treturn oauth2.GenerateVerifier()\n}\n\nfunc discoverPKCE(ctx context.Context, d pkceDependencies, p OAuth2Provider) (pkceSupported bool, err error) {\n\tif p.Config().IssuerURL == \"\" {\n\t\treturn false, errors.New(\"Issuer URL must be set to autodiscover PKCE support\")\n\t}\n\n\tctx = gooidc.ClientContext(ctx, d.HTTPClient(ctx).HTTPClient)\n\tgp, err := gooidc.NewProvider(ctx, p.Config().IssuerURL)\n\tif err != nil {\n\t\treturn false, errors.Wrap(err, \"failed to initialize provider\")\n\t}\n\tvar claims struct {\n\t\tCodeChallengeMethodsSupported []string `json:\"code_challenge_methods_supported\"`\n\t}\n\tif err := gp.Claims(&claims); err != nil {\n\t\treturn false, errors.Wrap(err, \"failed to deserialize provider claims\")\n\t}\n\treturn slices.Contains(claims.CodeChallengeMethodsSupported, \"S256\"), nil\n}\n","sourceCodeStart":47,"sourceCodeEnd":81,"githubUrl":"https://github.com/ory/kratos/blob/b86338da04a040247a07f46100a86dcfb3875909/selfservice/strategy/oidc/pkce.go#L47-L81","documentation":"discoverPKCE autodetects whether an OIDC provider supports PKCE by performing OIDC discovery against the provider's IssuerURL. If IssuerURL is empty there is nothing to discover against, so it errors. discoverPKCE is called by maybePKCE when the provider config does not explicitly set a PKCE mode.","triggerScenarios":"Configuring an OIDC social-signin provider without an `issuer_url` while `pkce` is set to `auto` (or left unset so it falls back to autodiscovery).","commonSituations":"Copy-pasted provider configs that set client_id/client_secret and auth_url/token_url manually but omit issuer_url; custom OAuth2 (non-OIDC) providers that have no issuer at all.","solutions":["Set `issuer_url` for the OIDC provider in selfservice.methods.oidc.config.providers[] (e.g. https://accounts.google.com)","Or set `pkce` explicitly to `force` or `never` in the provider config so autodiscovery is skipped","For non-OIDC/OAuth2-only providers without an issuer, use pkce: never (or force if the provider supports it)","Verify the issuer_url matches the provider's published issuer exactly (discovery fetches {issuer_url}/.well-known/openid-configuration)"],"exampleFix":"// before (config.yml)\nselfservice:\n  methods:\n    oidc:\n      config:\n        providers:\n          - id: google\n            client_id: ...\n            client_secret: ...\n// after\nselfservice:\n  methods:\n    oidc:\n      config:\n        providers:\n          - id: google\n            client_id: ...\n            client_secret: ...\n            issuer_url: https://accounts.google.com\n            # or: pkce: never  (skip autodiscovery)","handlingStrategy":"validation","validationCode":"for _, p := range cfg.SelfService.OIDC.Providers {\n  if (p.PKCE == \"\" || p.PKCE == \"auto\") && p.IssuerURL == \"\" {\n    return errors.Errorf(\"provider %q: issuer_url required for PKCE autodiscovery\", p.ID)\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set issuer_url for OIDC providers; it is required for discovery and JWKS anyway","Set pkce explicitly (force/never) when the provider is OAuth2-only without an issuer","Validate provider configs in CI before deployment"],"tags":["oidc","oauth2","pkce","config"],"backgroundTag":"missing-required-config-field","analyzedSha":"b86338da04a040247a07f46100a86dcfb3875909","analyzedAt":"2026-09-07T15:58:15.934Z","contentChangedAt":"2026-09-07T15:58:15.934Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}