# Jenkins and plugin LDAP over TLS

**URL:** <https://community.jenkins.io/t/jenkins-and-plugin-ldap-over-tls/16219>\
**Category:** Using Jenkins\
**Created:** [June 21, 2024, 1:29pm UTC](https://community.jenkins.io/t/jenkins-and-plugin-ldap-over-tls/16219 "2024-06-21T13:29:53Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon45870069](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@anon45870069](https://community.jenkins.io/u/anon45870069)\
**Post date:** [June 21, 2024, 1:29pm UTC](https://community.jenkins.io/t/jenkins-and-plugin-ldap-over-tls/16219/1 "2024-06-21T13:29:53Z")

</div>

Hi, I’m a trainee network administrator for a company. I set up LDAP authentication with the plugin for Jenkins without any problem.  
Then I wanted to set up LDAPS authentication.  
My first error was that I hadn’t put the certificate in the keystore.  
To fix the error I used keytool with the following command:  
`sudo keytool -importcert -file certificate.crt -keystore /usr/lib/jvm/java-17-openjdk-amd64/lib/security/cacerts -alias "certificate"`

But now I’m faced with the error :

> Unable to connect to ldaps://:636 : javax.naming.CommunicationException: :636 [Root exception is javax.net.ssl.SSLException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty]

My environment is as follows:

- a virtual machine running Ubuntu 24.04 LTS with apache, jenkins, ownCloud and Subversion
- a physical Windows Server 2022 machine, where I access Jenkins

---

<div class="post-metadata">

**Author:** ![kikmon](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/kikmon/32/2837_2.png) [@kikmon](https://community.jenkins.io/u/kikmon)\
**Post date:** [June 24, 2024, 1:57am UTC](https://community.jenkins.io/t/jenkins-and-plugin-ldap-over-tls/16219/2 "2024-06-24T01:57:16Z")

</div>

Hi

When troubleshooting these issues, I like to use the SSLPoke tool at [GitHub - rksk/SSLPoke: Java tool for testing validity (certificates) of trust stores](https://github.com/rksk/SSLPoke)  
That way you can confirm if it’s an SSL issue / cert issue or a Jenkins configuration issue.  
Then, I think the proper modern way of managing the cacerts is the use a jks file and pass it as an argument when starting Jenkins  
Finally, you may want to use Jenkins official docker image to help with reproducibility / isolation of the whole setup.

if you investigation points to a Jenkins config issue, could you post the relevant section of the Jenkins config file ?

---

<div class="post-metadata">

**Author:** ![anon45870069](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@anon45870069](https://community.jenkins.io/u/anon45870069)\
**Post date:** [June 24, 2024, 7:33am UTC](https://community.jenkins.io/t/jenkins-and-plugin-ldap-over-tls/16219/3 "2024-06-24T07:33:24Z")

</div>

it’s detail of the error :

```auto
java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
	at java.base/java.security.cert.PKIXParameters.setTrustAnchors(PKIXParameters.java:200)
	at java.base/java.security.cert.PKIXParameters.<init>(PKIXParameters.java:120)
	at java.base/java.security.cert.PKIXBuilderParameters.<init>(PKIXBuilderParameters.java:104)
	at java.base/sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:98)
Caused: java.lang.RuntimeException: Unexpected error
	at java.base/sun.security.validator.PKIXValidator.<init>(PKIXValidator.java:101)
	at java.base/sun.security.validator.Validator.getInstance(Validator.java:181)
	at java.base/sun.security.ssl.X509TrustManagerImpl.getValidator(X509TrustManagerImpl.java:309)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrustedInit(X509TrustManagerImpl.java:183)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:198)
	at java.base/sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:132)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.checkServerCerts(CertificateMessage.java:1335)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.onConsumeCertificate(CertificateMessage.java:1226)
	at java.base/sun.security.ssl.CertificateMessage$T13CertificateConsumer.consume(CertificateMessage.java:1169)
	at java.base/sun.security.ssl.SSLHandshake.consume(SSLHandshake.java:396)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:480)
	at java.base/sun.security.ssl.HandshakeContext.dispatch(HandshakeContext.java:458)
	at java.base/sun.security.ssl.TransportContext.dispatch(TransportContext.java:201)
	at java.base/sun.security.ssl.SSLTransport.decode(SSLTransport.java:172)
	at java.base/sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1510)
	at java.base/sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1425)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:455)
Caused: javax.net.ssl.SSLException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty
	at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:133)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:378)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321)
	at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:316)
	at java.base/sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1712)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:470)
	at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:426)
	at java.naming/com.sun.jndi.ldap.Connection.initialSSLHandshake(Connection.java:365)
	at java.naming/com.sun.jndi.ldap.Connection.createSocket(Connection.java:290)
	at java.naming/com.sun.jndi.ldap.Connection.<init>(Connection.java:232)
Caused: javax.naming.CommunicationException: 192.168.0.56:636 [Root exception is javax.net.ssl.SSLException: Unexpected error: java.security.InvalidAlgorithmParameterException: the trustAnchors parameter must be non-empty]
	at java.naming/com.sun.jndi.ldap.Connection.<init>(Connection.java:253)
	at java.naming/com.sun.jndi.ldap.LdapClient.<init>(LdapClient.java:137)
	at java.naming/com.sun.jndi.ldap.LdapClient.getInstance(LdapClient.java:1616)
	at java.naming/com.sun.jndi.ldap.LdapCtx.connect(LdapCtx.java:2848)
	at java.naming/com.sun.jndi.ldap.LdapCtx.<init>(LdapCtx.java:348)
	at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxFromUrl(LdapCtxFactory.java:229)
	at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURL(LdapCtxFactory.java:189)
	at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getUsingURLs(LdapCtxFactory.java:247)
	at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getLdapCtxInstance(LdapCtxFactory.java:154)
	at java.naming/com.sun.jndi.ldap.LdapCtxFactory.getInitialContext(LdapCtxFactory.java:84)
	at java.naming/javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:732)
	at java.naming/javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:305)
	at java.naming/javax.naming.InitialContext.init(InitialContext.java:236)
	at java.naming/javax.naming.InitialContext.<init>(InitialContext.java:208)
	at java.naming/javax.naming.directory.InitialDirContext.<init>(InitialDirContext.java:130)
	at jenkins.security.plugins.ldap.LDAPConfiguration$LDAPConfigurationDescriptor.doCheckServer(LDAPConfiguration.java:432)
	at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:732)
	at org.kohsuke.stapler.Function$MethodFunction.invoke(Function.java:397)
	at org.kohsuke.stapler.Function$InstanceFunction.invoke(Function.java:409)
	at org.kohsuke.stapler.Function.bindAndInvoke(Function.java:207)
	at org.kohsuke.stapler.SelectionInterceptedFunction$Adapter.invoke(SelectionInterceptedFunction.java:36)
	at org.kohsuke.stapler.verb.HttpVerbInterceptor.invoke(HttpVerbInterceptor.java:48)
	at org.kohsuke.stapler.SelectionInterceptedFunction.bindAndInvoke(SelectionInterceptedFunction.java:26)
	at org.kohsuke.stapler.Function.bindAndInvokeAndServeResponse(Function.java:140)
	at org.kohsuke.stapler.MetaClass$11.doDispatch(MetaClass.java:558)
	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:59)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:770)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:900)
	at org.kohsuke.stapler.MetaClass$4.doDispatch(MetaClass.java:289)
	at org.kohsuke.stapler.NameBasedDispatcher.dispatch(NameBasedDispatcher.java:59)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:770)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:900)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:836)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:900)
	at org.kohsuke.stapler.MetaClass$9.dispatch(MetaClass.java:475)
	at org.kohsuke.stapler.Stapler.tryInvoke(Stapler.java:770)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:900)
	at org.kohsuke.stapler.Stapler.invoke(Stapler.java:698)
	at org.kohsuke.stapler.Stapler.service(Stapler.java:248)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:590)
	at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:764)
	at org.eclipse.jetty.servlet.ServletHandler$ChainEnd.doFilter(ServletHandler.java:1665)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:163)
	at jenkins.metrics.impl.MetricsFilter.doFilter(MetricsFilter.java:125)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:160)
	at jenkins.util.HttpServletFilter$1.doFilter(HttpServletFilter.java:76)
	at hudson.util.PluginServletFilter$1.doFilter(PluginServletFilter.java:160)
	at hudson.util.PluginServletFilter.doFilter(PluginServletFilter.java:166)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at jenkins.ErrorAttributeFilter.doFilter(ErrorAttributeFilter.java:29)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at hudson.security.csrf.CrumbFilter.doFilter(CrumbFilter.java:154)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:94)
	at jenkins.security.AcegiSecurityExceptionFilter.doFilter(AcegiSecurityExceptionFilter.java:52)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at hudson.security.UnwrapSecurityExceptionFilter.doFilter(UnwrapSecurityExceptionFilter.java:54)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:126)
	at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:120)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:100)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:110)
	at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:101)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:227)
	at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:221)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at jenkins.security.BasicHeaderProcessor.doFilter(BasicHeaderProcessor.java:97)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:117)
	at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
	at hudson.security.HttpSessionContextIntegrationFilter2.doFilter(HttpSessionContextIntegrationFilter2.java:63)
	at hudson.security.ChainedServletFilter$1.doFilter(ChainedServletFilter.java:99)
	at hudson.security.ChainedServletFilter.doFilter(ChainedServletFilter.java:111)
	at hudson.security.HudsonFilter.doFilter(HudsonFilter.java:172)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at org.kohsuke.stapler.compression.CompressionFilter.doFilter(CompressionFilter.java:53)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at hudson.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:86)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at org.kohsuke.stapler.DiagnosticThreadNameFilter.doFilter(DiagnosticThreadNameFilter.java:30)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at jenkins.security.SuspiciousRequestFilter.doFilter(SuspiciousRequestFilter.java:38)
	at org.eclipse.jetty.servlet.FilterHolder.doFilter(FilterHolder.java:202)
	at org.eclipse.jetty.servlet.ServletHandler$Chain.doFilter(ServletHandler.java:1635)
	at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:527)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:131)
	at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:569)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:223)
	at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1580)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:221)
	at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1384)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:176)
	at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:484)
	at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1553)
	at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:174)
	at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1306)
	at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:129)
	at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:122)
	at org.eclipse.jetty.server.Server.handle(Server.java:563)
	at org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1598)
	at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:753)
	at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:501)
	at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:287)
	at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:314)
	at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
	at org.eclipse.jetty.io.SelectableChannelEndPoint$1.run(SelectableChannelEndPoint.java:53)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.runTask(AdaptiveExecutionStrategy.java:421)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.consumeTask(AdaptiveExecutionStrategy.java:390)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.tryProduce(AdaptiveExecutionStrategy.java:277)
	at org.eclipse.jetty.util.thread.strategy.AdaptiveExecutionStrategy.run(AdaptiveExecutionStrategy.java:199)
	at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:411)
	at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:969)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.doRunJob(QueuedThreadPool.java:1194)
	at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1149)
	at java.base/java.lang.Thread.run(Thread.java:840)

```

---

<div class="post-metadata">

**Author:** ![anon45870069](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@anon45870069](https://community.jenkins.io/u/anon45870069)\
**Post date:** [June 24, 2024, 7:52am UTC](https://community.jenkins.io/t/jenkins-and-plugin-ldap-over-tls/16219/4 "2024-06-24T07:52:27Z")

</div>

I try Java tool for testing validity (certificates) of trust stores  
`java -Djavax.net.ssl.trustStore=/usr/lib/jvm/java-17-openjdk-amd64/lib/security/cacerts SSLPoke <domain name of the ldap server> 636`

And i got this error :

```auto
Erreur : impossible de trouver ou de charger la classe principale SSLPoke
Causé par : java.lang.ClassNotFoundException: SSLPoke

```

Traduction :

```auto
Error : unable to find or load the SSLPoke main class
Caused by: java.lang.ClassNotFoundException: SSLPoke

```

BTW : i’m french

---

<div class="post-metadata">

**Author:** ![kikmon](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/kikmon/32/2837_2.png) [@kikmon](https://community.jenkins.io/u/kikmon)\
**Post date:** [June 24, 2024, 8:29am UTC](https://community.jenkins.io/t/jenkins-and-plugin-ldap-over-tls/16219/5 "2024-06-24T08:29:52Z")

</div>

no worry, I do speak french too 🙂  
I think you need to compile the java tool first (using javac), after that, the commandline should work

---

<div class="post-metadata">

**Author:** ![anon45870069](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@anon45870069](https://community.jenkins.io/u/anon45870069)\
**Post date:** [June 24, 2024, 9:41am UTC](https://community.jenkins.io/t/jenkins-and-plugin-ldap-over-tls/16219/6 "2024-06-24T09:41:56Z")

</div>

Should I put the java file in a specific place?

---

<div class="post-metadata">

**Author:** ![anon45870069](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@anon45870069](https://community.jenkins.io/u/anon45870069)\
**Post date:** [June 24, 2024, 9:45am UTC](https://community.jenkins.io/t/jenkins-and-plugin-ldap-over-tls/16219/7 "2024-06-24T09:45:12Z")

</div>

And for this example :

```auto
java -Djavax.net.ssl.trustStore=/path/to/app/client-truststore.jks SSLPoke mydomain.com 443

```

“[mydomain.com](http://mydomain.com)” should be my ldap server or the machine where there is Jenkins ?

---

<div class="post-metadata">

**Author:** ![kikmon](https://dub1.discourse-cdn.com/flex013/user_avatar/community.jenkins.io/kikmon/32/2837_2.png) [@kikmon](https://community.jenkins.io/u/kikmon)\
**Post date:** [June 25, 2024, 2:12am UTC](https://community.jenkins.io/t/jenkins-and-plugin-ldap-over-tls/16219/8 "2024-06-25T02:12:01Z")

</div>

I think in your case you want to make sure the SSL connection from your Jenkins server to your LDAPs is working fine, so use your LDAP server. Don’t forget to adjust your port. You probably want to test 636 and 3269  
To compile the tool, make sure you have the JDK installed, open a terminal in the folder of the SSLPoke.java, and run ‘javac SSLPoke.java’  
This will generate a SSLPoke.class, and then you can use java SSLPoke to execute it

---

<div class="post-metadata">

**Author:** ![anon45870069](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@anon45870069](https://community.jenkins.io/u/anon45870069)\
**Post date:** [June 25, 2024, 7:03am UTC](https://community.jenkins.io/t/jenkins-and-plugin-ldap-over-tls/16219/9 "2024-06-25T07:03:35Z")

</div>

okay, i will see this
