{"record":{"id":"f11b5a412e40869d","repo":"Kareadita/Kavita","slug":"errors-oidc-role-not-assigned","errorCode":null,"errorMessage":"errors.oidc.role-not-assigned","messagePattern":"errors\\.oidc\\.role-not-assigned","errorType":"exception","errorClass":"KavitaException","httpStatus":null,"severity":"error","filePath":"Kavita.Services/OidcService.cs","lineNumber":215,"sourceCode":"    /// Tries to construct a new account from the OIDC Principal may fail if required conditions aren't met\n    /// </summary>\n    /// <param name=\"request\"></param>\n    /// <param name=\"principal\"></param>\n    /// <param name=\"settings\"></param>\n    /// <param name=\"oidcId\"></param>\n    /// <returns></returns>\n    /// <exception cref=\"KavitaException\"></exception>\n    private async Task<AppUser?> CreateNewAccount(HttpRequest request, ClaimsPrincipal principal, OidcConfigDto settings, string oidcId)\n    {\n        // Check if the token contains the login role, or the admin role\n        var isAllowedToBeCreated = principal.GetClaimsWithPrefix(settings.RolesClaim, settings.RolesPrefix)\n            .Intersect([PolicyConstants.LoginRole, PolicyConstants.AdminRole], StringComparer.OrdinalIgnoreCase)\n            .Any();\n\n        if (settings.SyncUserSettings && !isAllowedToBeCreated)\n        {\n            logger.LogDebug(\"Login role was not found under claim {Claim} with prefix {Prefix}\", settings.RolesClaim, settings.RolesPrefix);\n            throw new KavitaException(\"errors.oidc.role-not-assigned\");\n        }\n\n        try\n        {\n            return await NewUserFromOpenIdConnect(request, settings, principal, oidcId);\n        }\n        catch (KavitaException)\n        {\n            throw;\n        }\n        catch (Exception e)\n        {\n            logger.LogError(e, \"An error occured creating a new user\");\n            throw new KavitaException(\"errors.oidc.creating-user\");\n        }\n\n    }\n","sourceCodeStart":197,"sourceCodeEnd":233,"githubUrl":"https://github.com/Kareadita/Kavita/blob/9c3e5400007f8a0282f7d883f2ad5e71716e514d/Kavita.Services/OidcService.cs#L197-L233","documentation":"Thrown in CreateNewAccount when settings.SyncUserSettings is on but the OIDC principal's role claims (filtered by RolesClaim + RolesPrefix) contain neither the LoginRole nor the AdminRole. Kavita won't auto-create users who lack an authorized role when role sync is enabled — a deny-by-default gate.","triggerScenarios":"First-time OIDC login with SyncUserSettings=true where the token's role claims — after applying RolesClaim and RolesPrefix — don't intersect {LoginRole, AdminRole}. The user isn't authorized to be provisioned.","commonSituations":"RolesClaim or RolesPrefix misconfigured so the claim path is wrong (roles under 'role' but configured as 'roles', or a prefix that strips too much); IdP doesn't emit role claims at all; user genuinely lacks the login role in the IdP.","solutions":["Verify the IdP actually issues role claims and that the user holds the LoginRole or AdminRole.","Re-check OIDC settings: RolesClaim must match the token's claim type and RolesPrefix must correctly trim the prefix.","If role sync isn't needed, disable SyncUserSettings (then SetDefaults applies DefaultRoles instead).","Decode the access token and inspect the configured claim + prefix against the actual claim names."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"var roles = principal.GetClaimsWithPrefix(settings.RolesClaim, settings.RolesPrefix);\nvar allowed = roles.Intersect(new[] { PolicyConstants.LoginRole, PolicyConstants.AdminRole }, StringComparer.OrdinalIgnoreCase);\nif (settings.SyncUserSettings && !allowed.Any())\n    return Forbid(\"User does not have a login or admin role.\");","typeGuard":"bool HasLoginRole(ClaimsPrincipal p, OidcConfigDto s) =>\n    !s.SyncUserSettings ||\n    p.GetClaimsWithPrefix(s.RolesClaim, s.RolesPrefix)\n     .Intersect(new[] { PolicyConstants.LoginRole, PolicyConstants.AdminRole }, StringComparer.OrdinalIgnoreCase)\n     .Any();","tryCatchPattern":"try { var user = await oidcService.LoginOrCreate(Request, principal, ct); }\ncatch (KavitaException ex) when (ex.Message == \"errors.oidc.role-not-assigned\")\n{ return Forbid(\"Contact an admin to be granted the login role.\"); }","preventionTips":["Verify RolesClaim and RolesPrefix match the token's actual claim names.","Ensure the IdP issues role claims and the user holds LoginRole/AdminRole.","Disable SyncUserSettings if role-based provisioning isn't required."],"tags":["oidc","authorization","roles","security"],"backgroundTag":null,"analyzedSha":"9c3e5400007f8a0282f7d883f2ad5e71716e514d","analyzedAt":"2026-08-13T19:06:05.897Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}