Versions (relevant - OpenSearch/Dashboard/Server OS/Browser):
Describe the issue :Empty file path for plugins.security.ssl.transport.truststore_filepath
Configuration : Active Directory Authc
Relevant Logs or Screenshots :
I have looked at these bug reports and topics:
opened 05:07PM - 01 Jun 22 UTC
closed 08:50PM - 27 Feb 23 UTC
bug
triaged
**What is the bug?**
When I attempt to authenticate to an LDAP server with `plu… gins.security.ssl.transport.pemtrustedcas_filepath` set, it's unable to validate the LDAP server's TLS certificate.
**How can one reproduce the bug?**
1. Set PEM Trusted CAs.
2. Try to authenticate against an LDAP server
**What is the expected behavior?**
The security module would use whatever trusted CA option is set to validate the TLS connection
**What is your host/environment?**
- OS: Ubuntu Linux 20.04
- Version 2.0.0
**Do you have any screenshots?**
This stack trace may be helpful:
```
[2022-06-01T16:54:43,991][DEBUG][c.a.d.a.l.b.LDAPAuthenticationBackend] [i-055541de785b4851d] Unable to authenticate user due to
org.ldaptive.LdapException: Unable to connect to any of those ldap servers [ldap.REMOVED:389] due to OpenSearchException[Empty file path for plugins.security.ssl.transport.truststore_filepath]
at com.amazon.dlic.auth.ldap.backend.LDAPAuthorizationBackend.getConnection0(LDAPAuthorizationBackend.java:364) ~[opensearch-security-2.0.0.0.jar:2.0.0.0]
at com.amazon.dlic.auth.ldap.backend.LDAPAuthorizationBackend$2.run(LDAPAuthorizationBackend.java:169) ~[opensearch-security-2.0.0.0.jar:2.0.0.0]
at com.amazon.dlic.auth.ldap.backend.LDAPAuthorizationBackend$2.run(LDAPAuthorizationBackend.java:159) ~[opensearch-security-2.0.0.0.jar:2.0.0.0]
at java.security.AccessController.doPrivileged(AccessController.java:569) ~[?:?]
at com.amazon.dlic.auth.ldap.backend.LDAPAuthorizationBackend.getConnection(LDAPAuthorizationBackend.java:159) ~[opensearch-security-2.0.0.0.jar:2.0.0.0]
at com.amazon.dlic.auth.ldap.backend.LDAPAuthenticationBackend.authenticate(LDAPAuthenticationBackend.java:87) [opensearch-security-2.0.0.0.jar:2.0.0.0]
at org.opensearch.security.auth.BackendRegistry$5.call(BackendRegistry.java:496) [opensearch-security-2.0.0.0.jar:2.0.0.0]
at org.opensearch.security.auth.BackendRegistry$5.call(BackendRegistry.java:490) [opensearch-security-2.0.0.0.jar:2.0.0.0]
at com.google.common.cache.LocalCache$LocalManualCache$1.load(LocalCache.java:4853) [guava-30.0-jre.jar:?]
at com.google.common.cache.LocalCache$LoadingValueReference.loadFuture(LocalCache.java:3529) [guava-30.0-jre.jar:?]
at com.google.common.cache.LocalCache$Segment.loadSync(LocalCache.java:2278) [guava-30.0-jre.jar:?]
at com.google.common.cache.LocalCache$Segment.lockedGetOrLoad(LocalCache.java:2155) [guava-30.0-jre.jar:?]
at com.google.common.cache.LocalCache$Segment.get(LocalCache.java:2045) [guava-30.0-jre.jar:?]
at com.google.common.cache.LocalCache.get(LocalCache.java:3951) [guava-30.0-jre.jar:?]
at com.google.common.cache.LocalCache$LocalManualCache.get(LocalCache.java:4848) [guava-30.0-jre.jar:?]
at org.opensearch.security.auth.BackendRegistry.authcz(BackendRegistry.java:490) [opensearch-security-2.0.0.0.jar:2.0.0.0]
at org.opensearch.security.auth.BackendRegistry.authenticate(BackendRegistry.java:299) [opensearch-security-2.0.0.0.jar:2.0.0.0]
at org.opensearch.security.filter.SecurityRestFilter.checkAndAuthenticateRequest(SecurityRestFilter.java:192) [opensearch-security-2.0.0.0.jar:2.0.0.0]
at org.opensearch.security.filter.SecurityRestFilter$1.handleRequest(SecurityRestFilter.java:125) [opensearch-security-2.0.0.0.jar:2.0.0.0]
at org.opensearch.rest.RestController.dispatchRequest(RestController.java:311) [opensearch-2.0.0.jar:2.0.0]
at org.opensearch.rest.RestController.tryAllHandlers(RestController.java:397) [opensearch-2.0.0.jar:2.0.0]
at org.opensearch.rest.RestController.dispatchRequest(RestController.java:240) [opensearch-2.0.0.jar:2.0.0]
at org.opensearch.security.ssl.http.netty.ValidatingDispatcher.dispatchRequest(ValidatingDispatcher.java:63) [opensearch-security-2.0.0.0.jar:2.0.0.0]
at org.opensearch.http.AbstractHttpServerTransport.dispatchRequest(AbstractHttpServerTransport.java:366) [opensearch-2.0.0.jar:2.0.0]
at org.opensearch.http.AbstractHttpServerTransport.handleIncomingRequest(AbstractHttpServerTransport.java:445) [opensearch-2.0.0.jar:2.0.0]
at org.opensearch.http.AbstractHttpServerTransport.incomingRequest(AbstractHttpServerTransport.java:356) [opensearch-2.0.0.jar:2.0.0]
at org.opensearch.http.netty4.Netty4HttpRequestHandler.channelRead0(Netty4HttpRequestHandler.java:55) [transport-netty4-client-2.0.0.jar:2.0.0]
at org.opensearch.http.netty4.Netty4HttpRequestHandler.channelRead0(Netty4HttpRequestHandler.java:41) [transport-netty4-client-2.0.0.jar:2.0.0]
at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at org.opensearch.http.netty4.Netty4HttpPipeliningHandler.channelRead(Netty4HttpPipeliningHandler.java:71) [transport-netty4-client-2.0.0.jar:2.0.0]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) [netty-codec-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) [netty-codec-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) [netty-codec-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:327) [netty-codec-4.1.73.Final.jar:4.1.73.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:299) [netty-codec-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286) [netty-handler-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103) [netty-codec-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.handler.ssl.SslHandler.unwrap(SslHandler.java:1371) [netty-handler-4.1.73.Final.jar:4.1.73.Final]
at io.netty.handler.ssl.SslHandler.decodeJdkCompatible(SslHandler.java:1234) [netty-handler-4.1.73.Final.jar:4.1.73.Final]
at io.netty.handler.ssl.SslHandler.decode(SslHandler.java:1283) [netty-handler-4.1.73.Final.jar:4.1.73.Final]
at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:510) [netty-codec-4.1.73.Final.jar:4.1.73.Final]
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:449) [netty-codec-4.1.73.Final.jar:4.1.73.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:279) [netty-codec-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:722) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysPlain(NioEventLoop.java:623) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:586) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496) [netty-transport-4.1.73.Final.jar:4.1.73.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:986) [netty-common-4.1.73.Final.jar:4.1.73.Final]
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [netty-common-4.1.73.Final.jar:4.1.73.Final]
at java.lang.Thread.run(Thread.java:833) [?:?]
Caused by: org.opensearch.OpenSearchException: Empty file path for plugins.security.ssl.transport.truststore_filepath
at org.opensearch.security.support.PemKeyReader.checkPath(PemKeyReader.java:263) ~[opensearch-security-2.0.0.0.jar:2.0.0.0]
at org.opensearch.security.support.PemKeyReader.resolve(PemKeyReader.java:336) ~[opensearch-security-2.0.0.0.jar:2.0.0.0]
at org.opensearch.security.support.PemKeyReader.resolve(PemKeyReader.java:322) ~[opensearch-security-2.0.0.0.jar:2.0.0.0]
at com.amazon.dlic.auth.ldap.backend.LDAPAuthorizationBackend.configureSSL(LDAPAuthorizationBackend.java:564) ~[opensearch-security-2.0.0.0.jar:2.0.0.0]
at com.amazon.dlic.auth.ldap.backend.LDAPAuthorizationBackend.getConnection0(LDAPAuthorizationBackend.java:287) ~[opensearch-security-2.0.0.0.jar:2.0.0.0]
... 81 more
```
**Do you have any additional context?**
Super thankful for y'all getting logging working #1689 in so I could uncover this bug 😄
I'm happy to set up a java-flavored truststore and such to move past this, but it is confusing behavior.
Versions (relevant - OpenSearch/Dashboard/Server OS/Browser):
OpenSearch:
"version" : {
"number" : "7.10.2",
"build_type" : "rpm",
"build_hash" : "e505b10357c03ae8d26d675172402f2f2144ef0f",
"build_date" : "2022-01-14T03:38:06.881862Z",
"build_snapshot" : false,
"lucene_version" : "8.10.1",
"minimum_wire_compatibility_version" : "6.8.0",
"minimum_index_compatibility_version" : "6.0.0-beta1"
},
OS:
NAME="CentOS Stream"
VERSION="8"
ID="centos"
ID_LIKE="rhel fed…
As I look to address this, I had a few questions about how these certs and functions relate. My system has a machine cert from our MS CA. I created the self signed certs because I was following along the documentation, and also didn’t want to explain tons of stuff to get the additional certs. Perhaps this was a mistake.
However, as it stands the I have the CA cert, the node cert and the admin cert for my single node instance of opensearch, with dashboards on the same server.
It create the recommended configurations:
config.yml → pemtrustedcas_filepath
opensearch.yml → plugins.security.ssl.transport.truststore_filepath
If I configure these with the CA chain for our MS CA, and the machine cert from our MS CA, won’t this screw up the transport between node, dashboards, etc?
Do I need to switch all of the certs to use the MS CA?
Yanlin
June 24, 2026, 4:26pm
3
Hi @subgenius ,
You should not need to replace all OpenSearch node/admin certificates with certificates issued by your Microsoft CA solely for LDAP/AD authentication.
There are two separate TLS areas involved:
OpenSearch TLS:
Transport TLS is used for node-to-node communication.
HTTP TLS is used for REST/API clients, including OpenSearch Dashboards connecting to OpenSearch.
LDAP/AD TLS:
This is used by the Security plugin when it connects to the LDAP/AD server.
By default, LDAP certificate validation can use the trust material configured for OpenSearch Security.
If your AD certificate is signed by a different CA, you can either:
add the AD CA to the existing trust chain, or
configure a dedicated LDAP trust CA using pemtrustedcas_filepath.
Reference and more detail: https://docs.opensearch.org/latest/security/authentication-backends/ldap/#certificate-validation
If you use a dedicated LDAP CA, make sure pemtrustedcas_filepath is configured in every LDAP config block where LDAP is used (for example both authc and authz if applicable).
Also, if you change the LDAP settings in config.yml, make sure the updated Security configuration is actually applied to the Security index, for example via securityadmin.sh or the Security REST API.
If the issue persists, could you share your redacted opensearch.yml and the relevant LDAP part of config.yml?
Thanks for the clear explanation! It answered exactly what I was asking. I configured the CA chain in the ldap authc config and promptly got a host validation error. I turned off host validation both in the config and in the jvm and now AD auth works
I have a conversation open with our AD admin about the redirect and where we can list that as a SAN in the cert.
It seems like these redirects may be a known issue with AD?
“Could not follow referral to ldaps://DomainDnsZones.[domain].lan”
“(certificate_unknown) No subject alternative DNS name matching DomainDnsZones.[domain].lan found”
Issue is resolved completely. After conferring with our AD admin, he provided several suggestions that don’t involve disabling ldap host verification (both in ldap config and jvm options)
For us at least, replacing the ldap port (636) with port 3269 allows querying the Global Catalog and eliminates the redirect that was causing the error.