apache/cassandra · critical · RuntimeException
Could not create SSL Context.
Error message
Could not create SSL Context.
What it means
BulkLoader.buildSSLOptions() wraps any IOException from SSLFactory.createSSLContext(clientEncryptionOptions, REQUIRED) in a RuntimeException 'Could not create SSL Context.'. It means the client TLS material (keystore/truststore files, passwords, algorithms) could not be loaded while building the native-protocol SSL engine. See tools/sstableloader/src/org/apache/cassandra/tools/BulkLoader.java:271.
Solutions
- Verify keystore/truststore paths exist and are readable by the loader process
- Check keystore/truststore passwords (test with `keytool -list`)
- Confirm the truststore contains the cluster's certificate chain
- If encryption isn't required for this load, run without SSL/client encryption
Example fix
// before
throw new RuntimeException("Could not create SSL Context.", e);
// after
throw new RuntimeException("Could not create SSL Context (check keystore/truststore paths and passwords): " + e.getMessage(), e); Defensive patterns
Strategy: validation
Validate before calling
// verify TLS material before running sstableloader String ksPath = clientEncryptionOptions.keystore; System.out.println(new File(ksPath).canRead() ? "keystore ok" : "keystore missing"); // verify passwords + trust chain: // keytool -list -keystore <ksPath> -storepass <pw> // keytool -list -keystore <tsPath> -storepass <tsPw>
Try / catch
try {
loader.load(options);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("Could not create SSL Context")) {
throw new IllegalStateException("Check client_encryption_options keystore/truststore", e);
}
throw e;
} Prevention
- Copy keystore/truststore files alongside any cassandra.yaml used by sstableloader
- Validate keystores with keytool before running loads
- Keep the truststore updated with the cluster's certificate chain
- If TLS isn't needed for the bulk load, run without SSL
When it happens
Trigger: Running sstableloader with encrypted client connections where the config's client_encryption_options point to a missing/unreadable keystore or truststore, wrong passwords, or an unavailable TLS algorithm/provider.
Common situations: Copying server cassandra.yaml to the loader host without the keystore files; typo'd keystore path or password; cluster certs missing from the truststore; Java version lacking the configured algorithm.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Certificate for expired on
- Dropping unsupported cipher_suite
- Error creating/initializing the SSL Context
- Error finding supported TLS Protocols
- Failed to create SSL context using
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/f94fc0e8c91b5418.
Report an issue: GitHub.
Appendix: source
Thrown at tools/sstableloader/src/org/apache/cassandra/tools/BulkLoader.java:271
}
}
private static SSLOptions buildSSLOptions(EncryptionOptions clientEncryptionOptions)
{
if (!clientEncryptionOptions.getEnabled())
{
return null;
}
SSLContext sslContext;
try
{
sslContext = SSLFactory.createSSLContext(clientEncryptionOptions, REQUIRED);
}
catch (IOException e)
{
throw new RuntimeException("Could not create SSL Context.", e);
}
// Temporarily override newSSLEngine to set accepted protocols until it is added to
// RemoteEndpointAwareJdkSSLOptions. See CASSANDRA-13325 and CASSANDRA-16362.
RemoteEndpointAwareJdkSSLOptions sslOptions = new RemoteEndpointAwareJdkSSLOptions(sslContext, clientEncryptionOptions.cipherSuitesArray())
{
@Override
protected SSLEngine newSSLEngine(SocketChannel channel, InetSocketAddress remoteEndpoint)
{
SSLEngine engine = super.newSSLEngine(channel, remoteEndpoint);
String[] acceptedProtocols = clientEncryptionOptions.acceptedProtocolsArray();
if (acceptedProtocols != null && acceptedProtocols.length > 0)
engine.setEnabledProtocols(acceptedProtocols);
return engine;
}
};View on GitHub (pinned to 88fd0f6a0e)