{"record":{"id":"b448c0670844392a","repo":"prestodb/presto","slug":"hive-metastore-error-b448c0","errorCode":"HIVE_METASTORE_ERROR","errorMessage":"External table location does not exist","messagePattern":"External table location does not exist","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-iceberg/src/main/java/com/facebook/presto/iceberg/hive/IcebergFileHiveMetastore.java","lineNumber":57,"sourceCode":"\n    @Inject\n    public IcebergFileHiveMetastore(HdfsEnvironment hdfsEnvironment, FileHiveMetastoreConfig config)\n    {\n        this(hdfsEnvironment, config.getCatalogDirectory(), config.getMetastoreUser());\n    }\n\n    public IcebergFileHiveMetastore(HdfsEnvironment hdfsEnvironment, String catalogDirectory, String metastoreUser)\n    {\n        super(hdfsEnvironment, catalogDirectory, metastoreUser);\n    }\n\n    @Override\n    protected void validateExternalLocation(Path externalLocation, Path catalogDirectory)\n            throws IOException\n    {\n        FileSystem externalFileSystem = hdfsEnvironment.getFileSystem(hdfsContext, externalLocation);\n        if (!externalFileSystem.isDirectory(externalLocation)) {\n            throw new PrestoException(HIVE_METASTORE_ERROR, \"External table location does not exist\");\n        }\n    }\n\n    @Override\n    protected void validateReplaceTableType(Table originTable, Table newTable)\n    {}\n\n    @Override\n    protected void renameTable(Path originalMetadataDirectory, Path newMetadataDirectory)\n    {\n        Optional<Runnable> rollbackAction = Optional.empty();\n        try {\n            // If the directory `.prestoPermissions` exists, copy it to the new table metadata directory\n            Path originTablePermissionDir = new Path(originalMetadataDirectory, PRESTO_PERMISSIONS_DIRECTORY_NAME);\n            Path newTablePermissionDir = new Path(newMetadataDirectory, PRESTO_PERMISSIONS_DIRECTORY_NAME);\n            if (metadataFileSystem.exists(originTablePermissionDir)) {\n                if (!FileUtil.copy(metadataFileSystem, originTablePermissionDir,\n                        metadataFileSystem, newTablePermissionDir, false, metadataFileSystem.getConf())) {","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-iceberg/src/main/java/com/facebook/presto/iceberg/hive/IcebergFileHiveMetastore.java#L39-L75","documentation":"When creating an external Iceberg table managed through the Hive metastore, IcebergFileHiveMetastore validates that the external location path exists as a directory on the configured filesystem. If the path is missing (or is a file, not a directory), it throws HIVE_METASTORE_ERROR with 'External table location does not exist'. The library refuses to register a table pointing at nonexistent storage.","triggerScenarios":"CREATE TABLE ... WITH (external_location = 'hdfs://...') where the directory does not exist on HDFS/S3, or exists as a file rather than a directory; typo in the location URI; wrong filesystem authority in the path.","commonSituations":"Typos in HDFS paths or bucket names; location deleted by a previous DROP or cleanup job; S3 prefix case-sensitivity mistakes; missing permissions making the directory invisible; HDFS federation path pointing at the wrong nameservice.","solutions":["Pre-create the directory: hadoop fs -mkdir -p <external_location> before CREATE TABLE.","Fix typos in the external_location URI (bucket/name, scheme, nameservice).","Verify the path is a directory, not a file, and check read permissions for the Presto user.","If the directory was deleted, restore it or point the table at an existing location."],"exampleFix":"// before\nCREATE TABLE iceberg.ext.t (...) WITH (external_location = 'hdfs://nn/user/etl/typo_dir')\n// after\n-- run first: hadoop fs -mkdir -p hdfs://nn/user/etl/correct_dir\nCREATE TABLE iceberg.ext.t (...) WITH (external_location = 'hdfs://nn/user/etl/correct_dir')","handlingStrategy":"validation","validationCode":"-- shell pre-check before CREATE TABLE\nhadoop fs -test -d hdfs://nn/user/etl/target_dir && echo OK || hadoop fs -mkdir -p hdfs://nn/user/etl/target_dir","typeGuard":null,"tryCatchPattern":"BEGIN\n  CREATE TABLE iceberg.ext.t (...) WITH (external_location = 'hdfs://nn/user/etl/target_dir');\nEXCEPTION\n  WHEN presto_error THEN\n    -- check path exists/is a directory and permissions, then retry\n    ROLLBACK;\nEND;","preventionTips":["Always mkdir the external location before CREATE TABLE ... external_location.","Double-check scheme/authority/bucket spelling in location URIs.","Verify the Presto user can read the directory.","Beware cleanup jobs deleting directories still referenced by tables."],"tags":[],"backgroundTag":null,"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"}