{"record":{"id":"f4b6273642a9f175","repo":"keycloak/keycloak","slug":"realm-url-not-set","errorCode":null,"errorMessage":"Realm URL not set","messagePattern":"Realm URL not set","errorType":"exception","errorClass":"VerificationException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/keycloak/TokenVerifier.java","lineNumber":110,"sourceCode":"\n            return true;\n        }\n    };\n\n    public static class RealmUrlCheck implements Predicate<JsonWebToken> {\n\n        private static final RealmUrlCheck NULL_INSTANCE = new RealmUrlCheck(null);\n\n        private final String realmUrl;\n\n        public RealmUrlCheck(String realmUrl) {\n            this.realmUrl = realmUrl;\n        }\n\n        @Override\n        public boolean test(JsonWebToken t) throws VerificationException {\n            if (this.realmUrl == null) {\n                throw new VerificationException(\"Realm URL not set\");\n            }\n\n            if (! this.realmUrl.equals(t.getIssuer())) {\n                throw new VerificationException(\"Invalid token issuer. Expected '\" + this.realmUrl + \"'\");\n            }\n\n            return true;\n        }\n    }\n\n    public static class TokenTypeCheck implements Predicate<JsonWebToken> {\n\n        private static final TokenTypeCheck INSTANCE_DEFAULT_TOKEN_TYPE = new TokenTypeCheck(Arrays.asList(TokenUtil.TOKEN_TYPE_BEARER));\n\n        private final List<String> tokenTypes;\n\n        public TokenTypeCheck(List<String> tokenTypes) {\n            this.tokenTypes = tokenTypes;","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/keycloak/keycloak/blob/66c7e15a3788de7764f07dd2558275a02770e16d/core/src/main/java/org/keycloak/TokenVerifier.java#L92-L128","documentation":"Thrown by RealmUrlCheck.test when the predicate was constructed with a null realmUrl. RealmUrlCheck validates that the token's issuer matches the expected realm URL; if no expected URL was supplied there is nothing to compare against, so the check fails immediately rather than silently passing. This is a configuration/usage error in the verifier, not a property of the token.","triggerScenarios":"Constructing new TokenVerifier.RealmUrlCheck(null) explicitly, or calling TokenVerifier.realmUrl(null) / not setting a realmUrl while the RealmUrlCheck remains in the predicate chain. The NULL_INSTANCE constant is reserved for disabling the check and must be used instead of passing null if you intend to skip it.","commonSituations":"A resource server that builds its verifier dynamically and forgets to set the realm URL from configuration, or code that constructs RealmUrlCheck with a config value that resolved to null.","solutions":["Provide a non-null realm URL to the verifier: TokenVerifier.create(...).realmUrl(issuer).verify().","If you intentionally do not want issuer checking, remove RealmUrlCheck from the chain (use withChecks(...) without it) or pass RealmUrlCheck.NULL_INSTANCE where the API expects a check.","Validate that the configuration source supplying the realm URL is populated before building the verifier."],"exampleFix":"// before: realmUrl resolves to null from config\nTokenVerifier.create(token, AccessToken.class)\n    .realmUrl(config.get(\"issuerUrl\")) // null!\n    .verify();\n\n// after: guard config, or omit the check\nString issuer = config.get(\"issuerUrl\");\nTokenVerifier<T> v = TokenVerifier.create(token, AccessToken.class);\nif (issuer != null) v.realmUrl(issuer);\nv.verify();","handlingStrategy":"validation","validationCode":"// Ensure a non-null realm URL before applying the check\nString issuer = config.get(\"realmIssuerUrl\");\nif (issuer == null) {\n  // either fail configuration or skip the RealmUrlCheck entirely\n  throw new IllegalStateException(\"realmIssuerUrl not configured\");\n}\nTokenVerifier.create(token, AccessToken.class).realmUrl(issuer).verify();","typeGuard":"static boolean hasRealmUrl(TokenVerifier.RealmUrlCheck c) {\n  // reflectively or by construction: only non-null realmUrl is usable\n  return c != null && c != TokenVerifier.RealmUrlCheck.NULL_INSTANCE;\n}","tryCatchPattern":"try {\n  verifier.realmUrl(realmUrl).verify();\n} catch (VerificationException e) {\n  if (e.getMessage().equals(\"Realm URL not set\")) {\n    // configuration bug — populate the issuer URL and retry\n  } else throw e;\n}","preventionTips":["Always set a concrete realm URL when issuer checking is desired.","Use RealmUrlCheck.NULL_INSTANCE or omit the check to disable it cleanly — never pass null.","Fail fast at startup if required config keys are absent."],"tags":["jwt","verification","realm","issuer","config"],"backgroundTag":null,"analyzedSha":"66c7e15a3788de7764f07dd2558275a02770e16d","analyzedAt":"2026-08-14T01:36:42.651Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}