apache/cassandra · error · IOException
Failed to create SSL context using
Error message
Failed to create SSL context using
What it means
validateSslContext() sanity-checks that both server and client Netty SSL contexts can actually be built from the given EncryptionOptions. When building the context throws for any reason (unreadable keystore, bad password, unsupported algorithm, invalid truststore), the exception is wrapped in an IOException whose message names the context being built; the original cause carries the real problem.
Solutions
- Read the 'caused by' of this IOException — it names the real failure (file not found, bad password, etc.) and fix that.
- Verify keystore/truststore paths and that the cassandra user can read them; check passwords in cassandra.yaml.
- Validate the store with keytool -list to confirm format (JKS/PKCS12/PEM) and certificate validity.
- Check java.security jdk.tls.disabledAlgorithms and protocol settings against the configured protocols/ciphers.
- After fixing certs, re-run validation or restart; for hot reload, ensure reloaded options pass validateSslContext.
Example fix
// before (config) server_encryption_options: keystore: /etc/cassandra/keystore.jks keystore_password: wrongpass // after server_encryption_options: keystore: /etc/cassandra/keystore.jks keystore_password: correctpass
Defensive patterns
Strategy: try-catch
Validate before calling
// Java: pre-flight check of keystore availability before validating SSL context
File ks = new File(options.keystore);
if (!ks.isFile() || !ks.canRead()) throw new IOException("Keystore unreadable: " + options.keystore);
if (options.keystore_password == null || options.keystore_password.isEmpty()) throw new IOException("Empty keystore password"); Try / catch
try {
SSLFactory.validateSslCerts(options);
} catch (IOException e) {
Throwable cause = e.getCause();
logger.error("SSL context validation failed: {} (cause: {})", e.getMessage(), cause, cause);
throw new ConfigurationException("Fix TLS config: " + (cause != null ? cause.getMessage() : e.getMessage()), e);
} Prevention
- Run keytool -list against configured keystores after certificate rotation
- Verify file permissions for the cassandra user on keystore/truststore paths
- Keep passwords in sync in cassandra.yaml and any secret store
- Test SSL config changes on a staging node with validateSslCerts before production
When it happens
Trigger: Calling validateSslContext (via checkCachedContextsForReload during hot reload, or validateSslCerts during startup/cert sanity checks) with EncryptionOptions pointing to a keystore/truststore that cannot be loaded or turned into a Netty SslContext.
Common situations: keystore/truststore file missing or unreadable due to permissions; wrong keystore_password/truststore_password; expired or corrupt certificates; algorithm disabled by jdk.tls.disabledAlgorithms; PEM vs JKS format mismatch after config changes.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
Related errors
- Certificate for expired on
- Could not create SSL Context.
- Dropping unsupported cipher_suite
- Error creating/initializing the SSL Context
- Error finding supported TLS Protocols
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/902125c319e57caf.
Report an issue: GitHub.
Appendix: source
Thrown at src/java/org/apache/cassandra/security/SSLFactory.java:418
finally
{
engine.closeInbound();
engine.closeOutbound();
ReferenceCountUtil.release(engine);
}
}
finally
{
ReferenceCountUtil.release(serverSslContext);
}
// Make sure it is possible to build the client context too
SslContext clientSslContext = createNettySslContext(options, clientAuth, SocketType.CLIENT);
ReferenceCountUtil.release(clientSslContext);
}
catch (Exception e)
{
throw new IOException("Failed to create SSL context using " + contextDescription, e);
}
}
}
/**
* Sanity checks all certificates to ensure we can actually load them
*/
public static void validateSslCerts(EncryptionOptions.ServerEncryptionOptions serverOpts, EncryptionOptions clientOpts) throws IOException
{
validateSslContext("server_encryption_options", serverOpts, REQUIRED, false);
validateSslContext("client_encryption_options", clientOpts, clientOpts.getClientAuth(), false);
}
static class CacheKey
{
private final EncryptionOptions encryptionOptions;
private final SocketType socketType;
private final String contextDescription;View on GitHub (pinned to 88fd0f6a0e)