{"record":{"id":"6be6ae381af4905c","repo":"prestodb/presto","slug":"arrow-flight-invalid-cert-error","errorCode":"ARROW_FLIGHT_INVALID_CERT_ERROR","errorMessage":"Error creating flight client, invalid certificate file: ","messagePattern":"Error creating flight client, invalid certificate file: ","errorType":"error_code","errorClass":"ArrowException","httpStatus":null,"severity":"error","filePath":"presto-base-arrow-flight/src/main/java/com/facebook/plugin/arrow/BaseArrowFlightClientHandler.java","lineNumber":96,"sourceCode":"            flightClientBuilder.verifyServer(config.getVerifyServer());\n            if (config.getFlightServerSSLCertificate() != null) {\n                trustedCertificate = Optional.of(newInputStream(Paths.get(config.getFlightServerSSLCertificate())));\n                flightClientBuilder.trustedCertificates(trustedCertificate.get()).useTls();\n            }\n            if (config.getFlightClientSSLCertificate() != null && config.getFlightClientSSLKey() != null) {\n                clientCertificate = Optional.of(newInputStream(Paths.get(config.getFlightClientSSLCertificate())));\n                clientKey = Optional.of(newInputStream(Paths.get(config.getFlightClientSSLKey())));\n                flightClientBuilder.clientCertificate(clientCertificate.get(), clientKey.get()).useTls();\n            }\n\n            return flightClientBuilder.build();\n        }\n        catch (Exception e) {\n            if (e.getCause() instanceof InvalidKeyException) {\n                throw new ArrowException(ARROW_FLIGHT_INVALID_KEY_ERROR, \"Error creating flight client, invalid key file: \" + e.getMessage(), e);\n            }\n            else if (e.getCause() instanceof CertificateException) {\n                throw new ArrowException(ARROW_FLIGHT_INVALID_CERT_ERROR, \"Error creating flight client, invalid certificate file: \" + e.getMessage(), e);\n            }\n            else {\n                throw new ArrowException(ARROW_FLIGHT_CLIENT_ERROR, \"Error creating flight client: \" + e.getMessage(), e);\n            }\n        }\n        finally {\n            if (trustedCertificate.isPresent()) {\n                try {\n                    trustedCertificate.get().close();\n                }\n                catch (IOException e) {\n                    logger.error(\"Error closing input stream for server certificate\", e);\n                }\n            }\n            if (clientCertificate.isPresent()) {\n                try {\n                    clientCertificate.get().close();\n                }","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-base-arrow-flight/src/main/java/com/facebook/plugin/arrow/BaseArrowFlightClientHandler.java#L78-L114","documentation":"In the same createFlightClient catch block, if the exception chain contains a java.security.cert.CertificateException, the handler throws ArrowException(ARROW_FLIGHT_INVALID_CERT_ERROR) with 'Error creating flight client, invalid certificate file: <msg>'. The trusted CA file or client certificate configured for the FlightClient could not be parsed or loaded, so the client cannot be built.","triggerScenarios":"Calling createFlightClient when the configured truststore/CA PEM or client cert file fails CertificateFactory parsing — bad PEM formatting, wrong file, expired/unparseable certificate, or empty file.","commonSituations":"Certificate chain file concatenated incorrectly (extra text/whitespace breaking PEM parsing); pointed at the key file instead of the cert; certificate expired or self-signed CA not matching server cert; cert re-issued in a format the JDK rejects.","solutions":["Open the cert file and confirm valid PEM content ('-----BEGIN CERTIFICATE-----') with no stray text.","Check you configured the certificate path, not the key path, in catalog properties.","Re-export the CA/client certificate; replace if expired or corrupted.","Verify the CA actually signed the Flight server certificate (openssl verify).","Confirm full-chain concatenation order (server/intermediate/root) if a bundle is used."],"exampleFix":"# before: cert path misconfigured\narrow.flight.trusted-certificate=/etc/tls/client.key\n# after\narrow.flight.trusted-certificate=/etc/tls/ca-cert.pem","handlingStrategy":"validation","validationCode":"// Validate the certificate parses before creating the client\njava.security.cert.CertificateFactory cf = java.security.cert.CertificateFactory.getInstance(\"X.509\");\ntry (java.io.InputStream in = java.nio.file.Files.newInputStream(java.nio.file.Path.of(certPath))) {\n    java.util.Collection<? extends java.security.cert.Certificate> certs = cf.generateCertificates(in);\n    if (certs.isEmpty()) throw new IllegalStateException(\"No certificates in \" + certPath);\n}","typeGuard":null,"tryCatchPattern":"try {\n    FlightClient client = handler.createFlightClient();\n} catch (ArrowException e) {\n    if (e.getErrorCode().getCode() == ARROW_FLIGHT_INVALID_CERT_ERROR.getCode()) {\n        // re-export/replace CA or client cert, then rebuild client\n    }\n    throw e;\n}","preventionTips":["Monitor certificate expiry and rotate before expiration.","Validate PEM bundles contain only certificates (no keys, no extra text).","Verify the CA against the server cert with `openssl verify -CAfile ca.pem server.pem`.","Mount cert files read-only and confirm paths after each config change."],"tags":["presto","arrow-flight","tls","certificate","mtls"],"backgroundTag":"invalid-tls-certificate","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}