keycloak/keycloak · error · VerificationException

Realm URL not set

Error message

Realm URL not set

What it means

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.

Source

Thrown at core/src/main/java/org/keycloak/TokenVerifier.java:110

            return true;
        }
    };

    public static class RealmUrlCheck implements Predicate<JsonWebToken> {

        private static final RealmUrlCheck NULL_INSTANCE = new RealmUrlCheck(null);

        private final String realmUrl;

        public RealmUrlCheck(String realmUrl) {
            this.realmUrl = realmUrl;
        }

        @Override
        public boolean test(JsonWebToken t) throws VerificationException {
            if (this.realmUrl == null) {
                throw new VerificationException("Realm URL not set");
            }

            if (! this.realmUrl.equals(t.getIssuer())) {
                throw new VerificationException("Invalid token issuer. Expected '" + this.realmUrl + "'");
            }

            return true;
        }
    }

    public static class TokenTypeCheck implements Predicate<JsonWebToken> {

        private static final TokenTypeCheck INSTANCE_DEFAULT_TOKEN_TYPE = new TokenTypeCheck(Arrays.asList(TokenUtil.TOKEN_TYPE_BEARER));

        private final List<String> tokenTypes;

        public TokenTypeCheck(List<String> tokenTypes) {
            this.tokenTypes = tokenTypes;

View on GitHub (pinned to 66c7e15a37)

Solutions

  1. Provide a non-null realm URL to the verifier: TokenVerifier.create(...).realmUrl(issuer).verify().
  2. 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.
  3. Validate that the configuration source supplying the realm URL is populated before building the verifier.

Example fix

// before: realmUrl resolves to null from config
TokenVerifier.create(token, AccessToken.class)
    .realmUrl(config.get("issuerUrl")) // null!
    .verify();

// after: guard config, or omit the check
String issuer = config.get("issuerUrl");
TokenVerifier<T> v = TokenVerifier.create(token, AccessToken.class);
if (issuer != null) v.realmUrl(issuer);
v.verify();
Defensive patterns

Strategy: validation

Validate before calling

// Ensure a non-null realm URL before applying the check
String issuer = config.get("realmIssuerUrl");
if (issuer == null) {
  // either fail configuration or skip the RealmUrlCheck entirely
  throw new IllegalStateException("realmIssuerUrl not configured");
}
TokenVerifier.create(token, AccessToken.class).realmUrl(issuer).verify();

Type guard

static boolean hasRealmUrl(TokenVerifier.RealmUrlCheck c) {
  // reflectively or by construction: only non-null realmUrl is usable
  return c != null && c != TokenVerifier.RealmUrlCheck.NULL_INSTANCE;
}

Try / catch

try {
  verifier.realmUrl(realmUrl).verify();
} catch (VerificationException e) {
  if (e.getMessage().equals("Realm URL not set")) {
    // configuration bug — populate the issuer URL and retry
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of keycloak/keycloak@66c7e15a37 (2026-08-14). Data as JSON: /api/errors/f4b6273642a9f175. Report an issue: GitHub.