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
ldap
Describe the bug
Keycloak seems to open and keep open for a while a new connection to the ldap server for each request. At least in below scenario:
I'm using the keycloak-admin-client 26.0.4 witch keycloak 26.1.4.
There is a writable Ldap User Federation set up with openLdap 2.5.13+dfsg-5
I access all users doing basically that here.
Nothing will be written back to keycloak. It's only read access
for(var user: allUsers) {
List<UserRepresentation> users = midwifeRealm.users().search(user.getUid(), true);
if (users.isEmpty()) {
// throw exception
}
userRepresentation = user.get(0);
// do something
// or do nothing. for testing I've just run through the loop.
}
At one point the users.isEmpty() call fails with:
Apr 03 00:01:48 intranet java[820274]: jakarta.ws.rs.BadRequestException: HTTP 400 Bad Request
Apr 03 00:01:48 intranet java[820274]: at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.handleErrorStatus(ClientInvocation.java:236)
Apr 03 00:01:48 intranet java[820274]: at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.extractResult(ClientInvocation.java:216)
Apr 03 00:01:48 intranet java[820274]: at org.jboss.resteasy.client.jaxrs.internal.proxy.extractors.BodyEntityExtractor.extractEntity(BodyEntityExtractor.java:59)
Apr 03 00:01:48 intranet java[820274]: at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invokeSync(ClientInvoker.java:136)
Apr 03 00:01:48 intranet java[820274]: at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientInvoker.invoke(ClientInvoker.java:103)
Apr 03 00:01:48 intranet java[820274]: at org.jboss.resteasy.client.jaxrs.internal.proxy.ClientProxy.invoke(ClientProxy.java:102)
Apr 03 00:01:48 intranet java[820274]: at jdk.proxy2/jdk.proxy2.$Proxy279.search(Unknown Source)
Apr 03 00:01:48 intranet java[820274]: at midwives.hebammenprofil.service.impl.KeycloakService.getUser(KeycloakService.java:152)
and openldap logs:
slapd[2974]: warning: cannot open /etc/hosts.deny: Too many open files
using pstree I could see that the keycloak container had around 1000 threads running.
Thread {Thread-7680} to {Thread-8713}. I didn't check if any thread number was missing, but they seemed to be sequential.
Even some minutes after the exception the threads where still there, and new requests failed. I didn't check how long it would take to everything go back to normal. At one point it does, since we've got a job running during night, which triggers that problem, but in the morning everything is back to normal. So in normal usage that problem doesn't appear.
After restarting openLdap all those Keycloak threads disappear and everything goes back to normal.
I checked if UserRepresentation is a resource that should be closed after using it. But couldn't find a close() possibility.
So as it seems keycloak starts up a new thread for each users.isEmpty() and/or users().search and/or users.get(0) where it access openldap. And keeps the thread and the connection to the ldap server open for a while instead of reusing the connection or just dropping it.
Is there a good reason to do so?
Is there a misconfiguration on my side?
Would it be possible to get a better exception than "jakarta.ws.rs.BadRequestException: HTTP 400 Bad Request"? It took me quite a while to realise, that the problem is not a badly formed request.
Version
26.1.4
Regression
- The issue is a regression
Expected behavior
To close or reuse the ldap connection.
Actual behavior
Keeping them open for a while
How to Reproduce?
see above
Anything else?
ldap config: