Apache NiFi Invalid SNI

The error message occurs to me when I'm trying to use Apache NiFi 2.x, either accessing with an IP address or a hostname that is not "localhost".


HTTP ERROR 400 Invalid SNI
URI:    /nifi
STATUS: 400
MESSAGE:    Invalid SNI
SERVLET:    -
CAUSED BY:  org.eclipse.jetty.http.BadMessageException: 400: Invalid SNI


org.eclipse.jetty.http.BadMessageException: 400: Invalid SNI
at org.eclipse.jetty.server.SecureRequestCustomizer.customize(SecureRequestCustomizer.java:266)
    at org.eclipse.jetty.server.SecureRequestCustomizer.customize(SecureRequestCustomizer.java:207)
    at org.eclipse.jetty.server.HttpChannel$RequestDispatchable.dispatch(HttpChannel.java:1594)
    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.HttpChannel.run(HttpChannel.java:461)
    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.produce(AdaptiveExecutionStrategy.java:193)
    at org.eclipse.jetty.http2.HTTP2Connection.produce(HTTP2Connection.java:208)
    at org.eclipse.jetty.http2.HTTP2Connection.onFillable(HTTP2Connection.java:155)
    at org.eclipse.jetty.http2.HTTP2Connection$FillableCallback.succeeded(HTTP2Connection.java:450)
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:100)
    at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:558)
    at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:379)
    at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:146)
    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:1583)
According to one answer from stackoverflow, the reason behind this is that
"Jetty 10, which is included with NiFi 2.0.0-M1, incorporates updates to the Server Name Indication processing during the TLS handshake. As a result of these changes, the default behavior does not support accessing NiFi using an IP address. Using a hostname or DNS name will avoid the SNI error and allow standard TLS negotiation to work."

and the default hostname is "localhost", and it is only allowed to access via https://localhost:8443/nifi for example. This has some issues in the case of deploying NiFi in Kubernetes, which will result in the error message that we mentioned above.

Also, modifying the nifi.web.https.host field of nifi.properties does not solve the problem! 

In order to use other hostnames rather than "localhost", we need our keystore and truststore which by default only contains "localhost" to have our desired hostname as a SAN entry according to one answer from here.  And we could generate your own keystore and truststore with needed SAN entry(s).


How to generate our own keystore and trustore with needed SAN entry(s)?

We can use Apache NiFi toolkits, which are separate things from NiFi and can be downloeaded from the NiFi download page). One of these is the TLS Toolkit (I only found it in NiFi Toolkit 1.26.0 but not in Toolkit 2.x).

Then we can follow the "Securing NiFi with TLS Toolkit" section of the Apache NiFi Walkthroughs guide to generate our own keystore and trustore. For example, if we our desired hostname is "nifi.local", then we can use the command: 


./bin/tls-toolkit.sh standalone -n "nifi.local"
This will generate three files as follows in a folder called nifi.local
  • keystore.jks, 
  • truststore.jks, and 
  • nifi.properties

You can use those newly generated keystore and trustore and the corresponding nifi.properties to overwrite the previous files in our NiFi conf folder.

Those three files are the main things relevant to our error message that we want to resolve, and for the rest, we can follow the other steps mentioned in the "Securing NiFi with TLS Toolkit" section of the Apache NiFi Walkthroughs guide.

Hope it helps in solving similar problems from your end!