Closed
Description
Before reporting an issue
- I have read and understood the above terms for submitting issues, and I understand that my issue may be closed without action if I do not follow them.
Area
storage
Describe the bug
During fetching user groups we may face
2025-06-10 11:14:57,477 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (executor-thread-472) Uncaught server error: java.lang.NullPointerException: Cannot invoke "org.keycloak.mod
els.GroupModel.getSubGroupsCount()" because the return value of "org.keycloak.models.cache.infinispan.GroupAdapter.getGroupModel()" is null
at org.keycloak.models.cache.infinispan.GroupAdapter.getSubGroupsCount(GroupAdapter.java:262)
at org.keycloak.utils.GroupUtils.populateSubGroupCount(GroupUtils.java:82)
at org.keycloak.utils.GroupUtils.lambda$populateGroupHierarchyFromSubGroups$2(GroupUtils.java:39)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.stream.SortedOps$RefSortingSink.end(SortedOps.java:395)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:261)
at java.base/java.util.stream.Sink$ChainedReference.end(Sink.java:261)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:510)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
at org.keycloak.utils.ClosingStream.forEach(ClosingStream.java:128)
at org.keycloak.utils.GroupUtils.populateGroupHierarchyFromSubGroups(GroupUtils.java:31)
at org.keycloak.services.resources.admin.GroupsResource.getGroups(GroupsResource.java:111)
at org.keycloak.services.resources.admin.GroupsResource$quarkusrestinvoker$getGroups_09ec752a8eec558a48a704f25fc7f0c07e766424.invoke(Unknown Source)
at org.jboss.resteasy.reactive.server.handlers.InvocationHandler.handle(InvocationHandler.java:29)
at io.quarkus.resteasy.reactive.server.runtime.QuarkusResteasyReactiveRequestContext.invokeHandler(QuarkusResteasyReactiveRequestContext.java:141)
at org.jboss.resteasy.reactive.common.core.AbstractResteasyReactiveContext.run(AbstractResteasyReactiveContext.java:147)
at io.quarkus.vertx.core.runtime.VertxCoreRecorder$15.runWith(VertxCoreRecorder.java:638)
at org.jboss.threads.EnhancedQueueExecutor$Task.doRunWith(EnhancedQueueExecutor.java:2675)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2654)
at org.jboss.threads.EnhancedQueueExecutor.runThreadBody(EnhancedQueueExecutor.java:1627)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1594)
at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:11)
at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:11)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:1583)
(after next occurrences it is shrinked to
2025-06-10 11:38:07,175 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (executor-thread-521) Uncaught server error: java.lang.NullPointerException
(without stack)
Version
26.2.5
Regression
- The issue is a regression
Expected behavior
No NPE during loading of user groups
Actual behavior
NPE is reproduced
How to Reproduce?
@Test
void createMultiDeleteMultiReadMulti() {
// create multiple groups
List<String> groupUuuids = new ArrayList<>();
IntStream.range(0, 100).forEach(groupIndex -> {
GroupRepresentation group = new GroupRepresentation();
group.setName("Test Group " + groupIndex);
try (Response response = realmResource.groups().add(group)) {
boolean created = response.getStatusInfo().getFamily() == Response.Status.Family.SUCCESSFUL;
if (created) {
final String createdResourceLocation = response.getHeaderString("Location");
String groupUuid = StringUtils.substringAfterLast(createdResourceLocation, "/");
groupUuuids.add(groupUuid);
} else {
fail("Failed to create group: " + response.getStatusInfo().getReasonPhrase());
}
}
});
AtomicBoolean deletedAll = new AtomicBoolean(false);
List<Exception> caughtExceptions = new CopyOnWriteArrayList<>();
// read groups in a separate thread
new Thread(() -> {
while (!deletedAll.get()) {
try {
// just loading briefs
realmResource.groups().groups(null, 0, Integer.MAX_VALUE, true);
} catch (Exception e) {
caughtExceptions.add(e);
}
}
}).start();
// delete groups
groupUuuids.forEach(groupUuid -> {
realmResource.groups().group(groupUuid).remove();
});
deletedAll.set(true);
assertThat(caughtExceptions, Matchers.empty());
}
Anything else?
- The test is green on 22.0.5, No NPE
- No sub-groups are created by us, just top-level groups
- No user federation enabled, the groups are pure Keycloak internal groups