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

  1. Open the key file and validate its format (PEM headers, PKCS#8 'BEGIN PRIVATE KEY' vs PKCS#1 'BEGIN RSA PRIVATE KEY').
  2. Convert the key with openssl, e.g. `openssl pkcs8 -topk8 -nocrypt -in key.pem -out key-pkcs8.pem`.
  3. If the key is encrypted, configure the passphrase or remove encryption.
  4. Re-export/re-download the key from your secret manager to rule out truncation/corruption.
  5. 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

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


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/3638a48ea97807c1. Report an issue: GitHub.