[ 
https://issues.apache.org/jira/browse/KAFKA-20572?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Hector Geraldino updated KAFKA-20572:
-------------------------------------
    Description: 
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}
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){code}
 

*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:*
{code:java}
  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{code}
  

Starting the worker with these properties will fail immediately throwing the 
NPE mentioned above 

  was:
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}
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){code}
 

*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 


> 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
>            Priority: Blocker
>
> 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}
> 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){code}
>  
> *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:*
> {code:java}
>   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{code}
>   
> 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)

Reply via email to