How to configure Active Directory LDAP timeouts to prevent socket-reader thread leaks

Last Reviewed:2026-08-09()
2 minute readKnowledge base

Issue

When the Active Directory plugin plugin is configured without LDAP read and connect timeouts, the JDK’s JNDI LDAP implementation spawns one background socket-reader thread per authentication request. Without a timeout, these threads block indefinitely polling the LDAP socket and are never released.

Over time, the accumulated threads exhaust the container’s OS-level thread/PID limit (OpenShift and Kubernetes default: 1024), causing login attempts to fail with:

java.lang.OutOfMemoryError: unable to create native thread: possibly out of memory or process/resource limits reached at java.lang.Thread.start0(Native Method) at com.sun.jndi.ldap.Connection.<init>(Connection.java:259) at ...ActiveDirectoryUnixAuthenticationProvider.lambda$retrieveUser$0 at ...ActiveDirectorySecurityRealm.authenticate2 at ...UsernamePasswordAuthenticationFilter.attemptAuthentication

This accumulates at approximately one leaked thread per 90 seconds, exhausting available threads within ~17 hours of pod startup. The controller recovers after a pod restart but fails again on the same schedule. Java heap usage and garbage collection remain healthy throughout — this is a thread count problem, not a memory problem.

Prerequisites:

  • Administrative access to the managed controller or client controller

  • For CasC-managed controllers: write access to the CasC bundle repository

Resolution

Option A: Configure via the Jenkins UI

  1. Navigate to Manage Jenkins  Security  Security Realm (Active Directory)  Advanced.

  2. Scroll to Environment Properties and add the following two entries:

    Name Value

    com.sun.jndi.ldap.read.timeout

    30000

    com.sun.jndi.ldap.connect.timeout

    5000

  3. Click Save.

For CasC-managed controllers, UI changes are overwritten when the CasC bundle is re-applied on pod restart. Use Option B to persist the configuration.

Option B: Configure via CasC jenkins.yaml

Add the environmentProperties block to the securityRealm section of the controller’s jenkins.yaml in the CasC bundle repository and commit the change:

jenkins: securityRealm: activeDirectory: domains: - name: "ldap.example.com" servers: "ldap.example.com:636" # ... your existing domain configuration ... environmentProperties: - name: "com.sun.jndi.ldap.read.timeout" value: "30000" - name: "com.sun.jndi.ldap.connect.timeout" value: "5000"

After committing, reload the CasC bundle from operations center or restart the managed controller pod.

Verify the fix

Confirm the settings are active by checking config.xml in $JENKINS_HOME for the environmentProperties block:

<environmentProperties> <hudson.plugins.active__directory.ActiveDirectorySecurityRealm_-EnvironmentProperty> <name>com.sun.jndi.ldap.read.timeout</name> <value>30000</value> </hudson.plugins.active__directory.ActiveDirectorySecurityRealm_-EnvironmentProperty> <hudson.plugins.active__directory.ActiveDirectorySecurityRealm_-EnvironmentProperty> <name>com.sun.jndi.ldap.connect.timeout</name> <value>5000</value> </hudson.plugins.active__directory.ActiveDirectorySecurityRealm_-EnvironmentProperty> </environmentProperties>

After applying the fix, monitor the controller for 24 hours to confirm login attempts no longer fail and no new unable to create native thread errors appear in the logs.

This article is part of our Knowledge Base and is provided for guidance-based purposes only. The solutions or workarounds described here are not officially supported by CloudBees and may not be applicable in all environments. Use at your own discretion, and test changes in a safe environment before applying them to production systems.