Hector Geraldino created KAFKA-20572:
----------------------------------------
Summary: Connect REST server throws NPE on startup when using
listener-prefixed SSL configs
Key: KAFKA-20572
URL: https://issues.apache.org/jira/browse/KAFKA-20572
Project: Kafka
Issue Type: Bug
Components: connect
Affects Versions: 4.2.0
Reporter: Hector Geraldino
Kafka Connect fails to start with a NullPointerException when the worker
configuration uses listener-prefixed SSL properties (e.g.
listeners.https.ssl.keystore.location) but does not explicitly set
listeners.https.ssl.cipher.suites.
This is a regression introduced in KAFKA-19112 (PR
#[20334|https://github.com/apache/kafka/pull/20334]).
*Stack trace*
{code:java}
{code}
*java.lang.NullPointerException: Cannot invoke "java.util.List.isEmpty()"
because "sslCipherSuites" is null
at
org.apache.kafka.connect.runtime.rest.util.SSLUtils.configureSslContextFactoryAlgorithms(SSLUtils.java:138)
at
org.apache.kafka.connect.runtime.rest.util.SSLUtils.createServerSideSslContextFactory(SSLUtils.java:50)
at
org.apache.kafka.connect.runtime.rest.util.SSLUtils.createServerSideSslContextFactory(SSLUtils.java:60)
at
org.apache.kafka.connect.runtime.rest.RestServer.createConnector(RestServer.java:171)
at
org.apache.kafka.connect.runtime.rest.RestServer.createConnector(RestServer.java:144)
at
org.apache.kafka.connect.runtime.rest.RestServer.createConnectors(RestServer.java:124)
at
org.apache.kafka.connect.runtime.rest.RestServer.<init>(RestServer.java:114)
at
org.apache.kafka.connect.runtime.rest.ConnectRestServer.<init>(ConnectRestServer.java:39)
at
org.apache.kafka.connect.cli.AbstractConnectCli.startConnect(AbstractConnectCli.java:131)
at
org.apache.kafka.connect.cli.AbstractConnectCli.run(AbstractConnectCli.java:95)
at
org.apache.kafka.connect.cli.ConnectDistributed.main(ConnectDistributed.java:112)*
*Root cause*
KAFKA-19112 changed the default of ssl.cipher.suites from null to List.of() in
SslConfigs.addClientSslSupport(), and correspondingly changed the guard in
SSLUtils.configureSslContextFactoryAlgorithms() from:
if (sslCipherSuites != null)
to:
if (!sslCipherSuites.isEmpty())
This is safe when the config is resolved through the normal ConfigDef path.
However, SSLUtils resolves configs via
{_}AbstractConfig.valuesWithPrefixAllOrNothing("listeners.https."){_}. This
method has an "all or nothing" semantic: if any _listeners.https.*_ prefixed
property is set, it returns only the prefixed entries without applying
ConfigDef defaults for missing keys.
I'd expect most deployments to set some listener-prefixed SSL properties (in
our case, we set keystore & truststore) but rely on the default cipher suites
({_}listeners.https.ssl.cipher.suites{_} is not set). This means the key is
absent from the returned map, Map.get() returns null, and the .isEmpty() call
throws an NPE.
*To reproduce:*
listeners=http://0.0.0.0:8083,https://0.0.0.0:8084
listeners.https.ssl.keystore.location=/path/to/keystore.jks
listeners.https.ssl.keystore.password=changeit
listeners.https.ssl.key.password=changeit
listeners.https.ssl.truststore.location=/path/to/truststore.jks
listeners.https.ssl.truststore.password=changeit
Starting the worker with these properties will fail immediately throwing the
NPE mentioned above
--
This message was sent by Atlassian Jira
(v8.20.10#820010)