keycloak/keycloak · error · RuntimeException
Error while updating policy [{}]. Client Scope [{}] could no
Error message
Error while updating policy [{}]. Client Scope [{}] could not be found. What it means
Thrown by ClientScopePolicyProviderFactory.updateClientScopes() when a referenced client scope cannot be resolved by name (realm.getClientScopesStream().filter(name == clientScopeName)) nor by id (realm.getClientScopeById(clientScopeName)). NOTE: there is a source bug — the message string is "Client Scope [" + "] could not be found." which omits the clientScopeName variable, so the brackets are always empty in the rendered message. The actual offending scope name is in the local variable clientScopeName but never interpolated.
Source
Thrown at authz/policy/common/src/main/java/org/keycloak/authorization/policy/provider/clientscope/ClientScopePolicyProviderFactory.java:238
}
private void updateClientScopes(Policy policy, AuthorizationProvider authorization,
Set<ClientScopeDefinition> clientScopes) {
RealmModel realm = authorization.getRealm();
Set<ClientScopePolicyRepresentation.ClientScopeDefinition> updatedClientScopes = new HashSet<>();
if (clientScopes != null) {
for (ClientScopePolicyRepresentation.ClientScopeDefinition definition : clientScopes) {
String clientScopeName = definition.getId();
ClientScopeModel clientScope = realm.getClientScopesStream()
.filter(scope -> scope.getName().equals(clientScopeName)).findAny().orElse(null);
if (clientScope == null) {
clientScope = realm.getClientScopeById(clientScopeName);
}
if (clientScope == null) {
throw new RuntimeException(
"Error while updating policy [" + policy.getName() + "]. Client Scope [" + "] could not be found.");
}
definition.setId(clientScope.getId());
updatedClientScopes.add(definition);
}
}
try {
policy.putConfig("clientScopes", JsonSerialization.writeValueAsString(updatedClientScopes));
} catch (IOException e) {
throw new RuntimeException("Failed to serialize client scopes", e);
}
}
}
View on GitHub (pinned to 66c7e15a37)
Solutions
- Since the message is empty, log the inbound representation's clientScope names/ids yourself before calling update to identify the bad reference.
- Validate each definition.getId() resolves via name or id in the target realm before update.
- Correct typos or remove stale references; ensure scopes exist (create them first if importing).
Example fix
// before: update throws with an empty 'Client Scope []' (source bug hides the name)
rep.setClientScopes(Collections.singleton(definitionWithName("public-scope-typo")));
authz.policies().update(rep);
// after: validate each scope reference before update, surfacing the real name
RealmModel realm = authorization.getRealm();
for (ClientScopeDefinition d : rep.getClientScopes()) {
String n = d.getId();
boolean exists = realm.getClientScopesStream().anyMatch(s -> s.getName().equals(n))
|| realm.getClientScopeById(n) != null;
if (!exists) throw new IllegalArgumentException("unknown client scope: " + n);
}
authz.policies().update(rep); Defensive patterns
Strategy: validation
Validate before calling
// Validate each client scope reference resolves (name then id) before update
RealmModel realm = authorization.getRealm();
for (ClientScopeDefinition d : rep.getClientScopes()) {
String n = d.getId();
boolean exists = realm.getClientScopesStream().anyMatch(s -> s.getName().equals(n))
|| realm.getClientScopeById(n) != null;
if (!exists) throw new IllegalArgumentException("unknown client scope: " + n);
} Type guard
private boolean clientScopeResolves(RealmModel realm, String nameOrId) {
return realm.getClientScopesStream().anyMatch(s -> s.getName().equals(nameOrId))
|| realm.getClientScopeById(nameOrId) != null;
} Try / catch
// The exception message is buggy (empty brackets); validate yourself.
for (ClientScopeDefinition d : rep.getClientScopes()) {
if (!clientScopeResolves(realm, d.getId()))
throw new IllegalArgumentException("unknown client scope: " + d.getId());
}
authz.policies().update(rep); Prevention
- Because the source message omits the scope name, log the inbound definitions yourself before update.
- Resolve scope references (name then id) before creating/updating client-scope policies.
- Create referenced client scopes before importing policies that use them.
When it happens
Trigger: Creating or updating a 'client-scope' policy whose clientScopes reference a scope name or id that does not exist in the realm. The lookup tries name first, then falls back to id; both failing raises this. Because of the message bug, you cannot read the offending name from the exception text — you must inspect the request/representation directly.
Common situations: Typo in a client scope name; the client scope was deleted after the policy was last edited; cross-realm confusion; using an id where a name is expected (or vice-versa) that doesn't match either; import referencing scopes not present in the target realm.
Related errors
- Error while updating policy [{}]. Client [{}] could not be f
- Permission id must not be null
- No client provided.
- Error while synchronizing client scopes with policy [{}].
- Could not parse client scopes [{}] from policy config [{}].
AI-assisted analysis of keycloak/keycloak@66c7e15a37 (2026-08-14).
Data as JSON: /api/errors/547dcb68f6281f89.
Report an issue: GitHub.