{"record":{"id":"eb08b036820275a1","repo":"prestodb/presto","slug":"generic-internal-error-eb08b0","errorCode":"GENERIC_INTERNAL_ERROR","errorMessage":"At least one of iceberg.rest.tls.keystore-path or iceberg.rest.tls.truststore-path must be configured when iceberg.rest.tls.enabled is true","messagePattern":"At least one of iceberg\\.rest\\.tls\\.keystore-path or iceberg\\.rest\\.tls\\.truststore-path must be configured when iceberg\\.rest\\.tls\\.enabled is true","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-iceberg/src/main/java/com/facebook/presto/iceberg/rest/PrestoRestTLSConfigurer.java","lineNumber":58,"sourceCode":"public class PrestoRestTLSConfigurer\n        implements TLSConfigurer\n{\n    static final String TLS_CONFIGURER_IMPL = \"rest.client.tls.configurer-impl\";\n    static final String KEYSTORE_PATH = \"rest.client.tls.keystore-path\";\n    static final String KEYSTORE_PASSWORD = \"rest.client.tls.keystore-password\";\n    static final String TRUSTSTORE_PATH = \"rest.client.tls.truststore-path\";\n    static final String TRUSTSTORE_PASSWORD = \"rest.client.tls.truststore-password\";\n\n    private SSLContext sslContext;\n\n    @Override\n    public void initialize(Map<String, String> properties)\n    {\n        String keystorePath = properties.get(KEYSTORE_PATH);\n        String truststorePath = properties.get(TRUSTSTORE_PATH);\n\n        if (keystorePath == null && truststorePath == null) {\n            throw new PrestoException(GENERIC_INTERNAL_ERROR,\n                    \"At least one of iceberg.rest.tls.keystore-path or iceberg.rest.tls.truststore-path \" +\n                            \"must be configured when iceberg.rest.tls.enabled is true\");\n        }\n\n        SslContextProvider sslContextProvider = new SslContextProvider(\n                Optional.ofNullable(keystorePath).map(File::new),\n                Optional.ofNullable(properties.get(KEYSTORE_PASSWORD)),\n                Optional.ofNullable(truststorePath).map(File::new),\n                Optional.ofNullable(properties.get(TRUSTSTORE_PASSWORD)));\n\n        this.sslContext = sslContextProvider.buildSslContext()\n                .orElseThrow(() -> new PrestoException(GENERIC_INTERNAL_ERROR,\n                        \"Failed to build SSL context for REST catalog TLS communication\"));\n    }\n\n    @Override\n    public SSLContext sslContext()\n    {","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-iceberg/src/main/java/com/facebook/presto/iceberg/rest/PrestoRestTLSConfigurer.java#L40-L76","documentation":"PrestoRestTLSConfigurer.initialize validates TLS configuration for the Iceberg REST catalog. When iceberg.rest.tls.enabled=true, at least one of keystore-path (client identity for mTLS) or truststore-path (server cert verification) must be present; otherwise the TLS layer cannot be built. It throws PrestoException with code GENERIC_INTERNAL_ERROR.","triggerScenarios":"Calling initialize() with a config map where iceberg.rest.tls.enabled=true but both iceberg.rest.tls.keystore-path and iceberg.rest.tls.truststore-path are absent (e.g. only passwords set, as in testInitializeWithPasswordOnlyThrows).","commonSituations":"Operators enable TLS for the REST catalog but forget to copy the keystore/truststore path properties into the catalog properties file; partial migration from a non-TLS catalog config; typos in property names so both lookups return null.","solutions":["Set either iceberg.rest.tls.keystore-path or iceberg.rest.tls.truststore-path (or both for mTLS) in the catalog properties when iceberg.rest.tls.enabled=true","Verify property names are spelled exactly (iceberg.rest.tls.keystore-path, iceberg.rest.tls.truststore-path)","If TLS is not actually required, set iceberg.rest.tls.enabled=false instead"],"exampleFix":"// before\niceberg.rest.tls.enabled=true\niceberg.rest.tls.keystore-password=secret\n// after\niceberg.rest.tls.enabled=true\niceberg.rest.tls.keystore-path=/etc/presto/tls/client.keystore\niceberg.rest.tls.truststore-path=/etc/presto/tls/truststore\niceberg.rest.tls.keystore-password=secret","handlingStrategy":"validation","validationCode":"if (Boolean.parseBoolean(props.getProperty(\"iceberg.rest.tls.enabled\"))\n        && props.getProperty(\"iceberg.rest.tls.keystore-path\") == null\n        && props.getProperty(\"iceberg.rest.tls.truststore-path\") == null) {\n    throw new IllegalArgumentException(\n        \"iceberg.rest.tls.enabled=true requires iceberg.rest.tls.keystore-path or iceberg.rest.tls.truststore-path\");\n}","typeGuard":null,"tryCatchPattern":"try { tlsConfigurer.initialize(properties); }\ncatch (PrestoException e) {\n    if (e.getErrorCode().getCode() == GENERIC_INTERNAL_ERROR.toErrorCode().getCode()) {\n        log.error(\"TLS enabled but no keystore/truststore path set; fix catalog properties\", e);\n    }\n    throw e;\n}","preventionTips":["When setting iceberg.rest.tls.enabled=true, always review the catalog properties for keystore/truststore paths","Use a config template/checklist for TLS-enabled catalogs (paths + passwords together)","Test catalog startup after TLS config changes in staging"],"tags":["tls","configuration","iceberg-rest"],"backgroundTag":"missing-tls-keystore-config","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"}