{"record":{"id":"10d06a96ca18f3c8","repo":"siyuan-note/siyuan","slug":"oidc-issuer-url-is-required","errorCode":null,"errorMessage":"OIDC issuer URL is required","messagePattern":"OIDC issuer URL is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"kernel/model/oidc.go","lineNumber":522,"sourceCode":"\t}\n}\n\nfunc validateOIDCConfiguration() error {\n\treturn ValidateOIDCConfiguration(Conf.GetOIDC())\n}\n\nfunc ValidateOIDCConfiguration(config *conf.OIDC) error {\n\tif config == nil || !config.Enabled {\n\t\treturn errors.New(\"OIDC login is not enabled\")\n\t}\n\tif config.ClientID == \"\" {\n\t\treturn errors.New(\"OIDC client ID is required\")\n\t}\n\tif config.Provider == conf.OIDCProviderGitHub && config.ClientSecret == \"\" {\n\t\treturn errors.New(\"GitHub OAuth client secret is required\")\n\t}\n\tif (config.Provider == conf.OIDCProviderCustom || config.Provider == conf.OIDCProviderMicrosoft) && config.IssuerURL == \"\" {\n\t\treturn errors.New(\"OIDC issuer URL is required\")\n\t}\n\tif (config.Provider == conf.OIDCProviderCustom || config.Provider == conf.OIDCProviderMicrosoft) && config.IssuerURL != \"\" {\n\t\tissuer, err := url.Parse(config.IssuerURL)\n\t\tif err != nil || issuer.Host == \"\" || issuer.User != nil || issuer.RawQuery != \"\" || issuer.Fragment != \"\" ||\n\t\t\t(issuer.Scheme != \"https\" && !util.IsLocalHostname(issuer.Hostname())) {\n\t\t\treturn errors.New(\"OIDC issuer URL must use HTTPS unless it is a loopback address\")\n\t\t}\n\t}\n\tif config.Provider != conf.OIDCProviderCustom && config.Provider != conf.OIDCProviderGoogle &&\n\t\tconfig.Provider != conf.OIDCProviderMicrosoft && config.Provider != conf.OIDCProviderGitHub {\n\t\treturn errors.New(\"Unsupported OIDC provider\")\n\t}\n\tif !config.AllowAll && len(config.ClaimRules) == 0 {\n\t\treturn errors.New(\"OIDC login requires at least one claim rule when Allow all users is disabled\")\n\t}\n\tfor _, rule := range config.ClaimRules {\n\t\tif rule == nil || rule.Claim == \"\" || len(rule.Values) == 0 {\n\t\t\treturn errors.New(\"OIDC claim rules must include a claim and at least one value\")","sourceCodeStart":504,"sourceCodeEnd":540,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/251596fc0de2f9528c00c224252fd073a99973f4/kernel/model/oidc.go#L504-L540","documentation":"Fourth check in ValidateOIDCConfiguration (kernel/model/oidc.go:522): provider is Custom or Microsoft but IssuerURL is empty. These providers need a discovery endpoint URL (the issuer), so an empty URL is rejected before the URL is parsed and scheme-checked.","triggerScenarios":"Selecting Custom or Microsoft in OIDC settings and saving without entering the issuer URL (e.g. https://login.microsoftonline.com/<tenant>/v2.0).","commonSituations":"Admin copied only the application (client) ID from Azure AD or a Keycloak admin panel and forgot the issuer/.well-known URL.","solutions":["Find the issuer URL from the provider's OpenID Connect discovery metadata (Azure: endpoint tab; Keycloak: realm settings -> OpenID Endpoint Configuration).","Paste the full HTTPS URL ending at the issuer root (not the .well-known path).","Re-save and re-run ValidateOIDCProviderConfiguration to confirm discovery succeeds."],"exampleFix":"// before\ncfg := &conf.OIDC{Enabled: true, Provider: conf.OIDCProviderMicrosoft, ClientID: \"abc\"}\n// after\ncfg := &conf.OIDC{Enabled: true, Provider: conf.OIDCProviderMicrosoft, ClientID: \"abc\",\n    IssuerURL: \"https://login.microsoftonline.com/\" + tenantID + \"/v2.0\"}","handlingStrategy":"validation","validationCode":"needsIssuer := cfg.Provider == conf.OIDCProviderCustom || cfg.Provider == conf.OIDCProviderMicrosoft\nif needsIssuer && cfg.IssuerURL == \"\" {\n    return errors.New(\"issuer URL required for this provider\")\n}\nreturn ValidateOIDCConfiguration(cfg)","typeGuard":"func issuerSatisfied(c *conf.OIDC) bool {\n    if c.Provider != conf.OIDCProviderCustom && c.Provider != conf.OIDCProviderMicrosoft {\n        return true\n    }\n    return c.IssuerURL != \"\"\n}","tryCatchPattern":null,"preventionTips":["Keep the issuer URL alongside the client ID in your secrets store.","For Azure AD, include the tenant ID in the URL; 'common' works for multi-tenant."],"tags":["oidc","issuer","microsoft","custom","config"],"backgroundTag":null,"analyzedSha":"251596fc0de2f9528c00c224252fd073a99973f4","analyzedAt":"2026-08-12T21:18:37.123Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}