prestodb/presto · error · ArrowException
ARROW_FLIGHT_INVALID_KEY_ERROR
ARROW_FLIGHT_INVALID_KEY_ERROR
Error message
Error creating flight client, invalid key file:
What it means
BaseArrowFlightClientHandler.createFlightClient builds a FlightClient with TLS material. When the exception chain contains a java.security.InvalidKeyException — the configured private key file is invalid or unreadable as a key — it is wrapped as ArrowException(ARROW_FLIGHT_INVALID_KEY_ERROR) with 'Error creating flight client, invalid key file: <msg>'. This indicates the client-side key used for mTLS is malformed, in the wrong format, or protected in an unsupported way.
Source
Thrown at presto-base-arrow-flight/src/main/java/com/facebook/plugin/arrow/BaseArrowFlightClientHandler.java:93
Optional<InputStream> clientKey = Optional.empty();
try {
FlightClient.Builder flightClientBuilder = FlightClient.builder(allocator, location);
flightClientBuilder.verifyServer(config.getVerifyServer());
if (config.getFlightServerSSLCertificate() != null) {
trustedCertificate = Optional.of(newInputStream(Paths.get(config.getFlightServerSSLCertificate())));
flightClientBuilder.trustedCertificates(trustedCertificate.get()).useTls();
}
if (config.getFlightClientSSLCertificate() != null && config.getFlightClientSSLKey() != null) {
clientCertificate = Optional.of(newInputStream(Paths.get(config.getFlightClientSSLCertificate())));
clientKey = Optional.of(newInputStream(Paths.get(config.getFlightClientSSLKey())));
flightClientBuilder.clientCertificate(clientCertificate.get(), clientKey.get()).useTls();
}
return flightClientBuilder.build();
}
catch (Exception e) {
if (e.getCause() instanceof InvalidKeyException) {
throw new ArrowException(ARROW_FLIGHT_INVALID_KEY_ERROR, "Error creating flight client, invalid key file: " + e.getMessage(), e);
}
else if (e.getCause() instanceof CertificateException) {
throw new ArrowException(ARROW_FLIGHT_INVALID_CERT_ERROR, "Error creating flight client, invalid certificate file: " + e.getMessage(), e);
}
else {
throw new ArrowException(ARROW_FLIGHT_CLIENT_ERROR, "Error creating flight client: " + e.getMessage(), e);
}
}
finally {
if (trustedCertificate.isPresent()) {
try {
trustedCertificate.get().close();
}
catch (IOException e) {
logger.error("Error closing input stream for server certificate", e);
}
}
if (clientCertificate.isPresent()) {View on GitHub (pinned to 55bb57d202)
Solutions
- Open the key file and validate its format (PEM headers, PKCS#8 'BEGIN PRIVATE KEY' vs PKCS#1 'BEGIN RSA PRIVATE KEY').
- Convert the key with openssl, e.g. `openssl pkcs8 -topk8 -nocrypt -in key.pem -out key-pkcs8.pem`.
- If the key is encrypted, configure the passphrase or remove encryption.
- Re-export/re-download the key from your secret manager to rule out truncation/corruption.
- Verify the key matches the certificate (same modulus/public key) issued for mTLS.
Example fix
# before: PKCS#1 key not accepted by JDK loader -----BEGIN RSA PRIVATE KEY----- # after: convert to PKCS#8 openssl pkcs8 -topk8 -nocrypt -in client.key -out client-pkcs8.key
Defensive patterns
Strategy: validation
Validate before calling
// Validate the key file parses before creating the client
byte[] pem = java.nio.file.Files.readAllBytes(java.nio.file.Path.of(keyPath));
String s = new String(pem, java.nio.file.StandardCharsets.US_ASCII);
if (!s.contains("BEGIN PRIVATE KEY") && !s.contains("BEGIN RSA PRIVATE KEY")) {
throw new IllegalStateException("Not a PEM key file: " + keyPath);
}
// Optional hard check:
java.security.KeyFactory.getInstance("RSA")
.generatePrivate(new java.security.spec.PKCS8EncodedKeySpec(parsePkcs8(pem))); Try / catch
try {
FlightClient client = handler.createFlightClient();
} catch (ArrowException e) {
if (e.getErrorCode().getCode() == ARROW_FLIGHT_INVALID_KEY_ERROR.getCode()) {
// fix key file format/passphrase, then rebuild client
}
throw e;
} Prevention
- Standardize on PKCS#8 PEM keys for all Flight mTLS configs.
- Validate key/cert pairs with `openssl pkey -in key.pem -check` and `openssl x509 -pubkey` matching.
- Never point key config at an encrypted key without configuring the passphrase.
- Check deployed key files for truncation after secret-manager pulls.
When it happens
Trigger: Calling createFlightClient (directly or via getFlightInfo/getSchema/any RPC) when loading the configured client key file into the SSL context throws InvalidKeyException (usually wrapped deeper, hence the getCause() walk).
Common situations: Key file in PKCS#8 vs PKCS#1 mismatch with the loader; encrypted key supplied without passphrase config; truncated or corrupted key file; key downloaded from a secret store with wrong encoding; Java version lacking support for the key algorithm.
Related errors
- ARROW_FLIGHT_INVALID_CERT_ERROR
- ARROW_FLIGHT_METADATA_ERROR
- ARROW_FLIGHT_CLIENT_ERROR
- ARROW_FLIGHT_INFO_ERROR
- ARROW_FLIGHT_METADATA_ERROR
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/3638a48ea97807c1.
Report an issue: GitHub.