prestodb/presto · error · PrestoException

HIVE_METASTORE_ERROR

HIVE_METASTORE_ERROR

Error message

External table location does not exist

What it means

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.

Source

Thrown at presto-iceberg/src/main/java/com/facebook/presto/iceberg/hive/IcebergFileHiveMetastore.java:57

    @Inject
    public IcebergFileHiveMetastore(HdfsEnvironment hdfsEnvironment, FileHiveMetastoreConfig config)
    {
        this(hdfsEnvironment, config.getCatalogDirectory(), config.getMetastoreUser());
    }

    public IcebergFileHiveMetastore(HdfsEnvironment hdfsEnvironment, String catalogDirectory, String metastoreUser)
    {
        super(hdfsEnvironment, catalogDirectory, metastoreUser);
    }

    @Override
    protected void validateExternalLocation(Path externalLocation, Path catalogDirectory)
            throws IOException
    {
        FileSystem externalFileSystem = hdfsEnvironment.getFileSystem(hdfsContext, externalLocation);
        if (!externalFileSystem.isDirectory(externalLocation)) {
            throw new PrestoException(HIVE_METASTORE_ERROR, "External table location does not exist");
        }
    }

    @Override
    protected void validateReplaceTableType(Table originTable, Table newTable)
    {}

    @Override
    protected void renameTable(Path originalMetadataDirectory, Path newMetadataDirectory)
    {
        Optional<Runnable> rollbackAction = Optional.empty();
        try {
            // If the directory `.prestoPermissions` exists, copy it to the new table metadata directory
            Path originTablePermissionDir = new Path(originalMetadataDirectory, PRESTO_PERMISSIONS_DIRECTORY_NAME);
            Path newTablePermissionDir = new Path(newMetadataDirectory, PRESTO_PERMISSIONS_DIRECTORY_NAME);
            if (metadataFileSystem.exists(originTablePermissionDir)) {
                if (!FileUtil.copy(metadataFileSystem, originTablePermissionDir,
                        metadataFileSystem, newTablePermissionDir, false, metadataFileSystem.getConf())) {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Pre-create the directory: hadoop fs -mkdir -p <external_location> before CREATE TABLE.
  2. Fix typos in the external_location URI (bucket/name, scheme, nameservice).
  3. Verify the path is a directory, not a file, and check read permissions for the Presto user.
  4. If the directory was deleted, restore it or point the table at an existing location.

Example fix

// before
CREATE TABLE iceberg.ext.t (...) WITH (external_location = 'hdfs://nn/user/etl/typo_dir')
// after
-- run first: hadoop fs -mkdir -p hdfs://nn/user/etl/correct_dir
CREATE TABLE iceberg.ext.t (...) WITH (external_location = 'hdfs://nn/user/etl/correct_dir')
Defensive patterns

Strategy: validation

Validate before calling

-- shell pre-check before CREATE TABLE
hadoop fs -test -d hdfs://nn/user/etl/target_dir && echo OK || hadoop fs -mkdir -p hdfs://nn/user/etl/target_dir

Try / catch

BEGIN
  CREATE TABLE iceberg.ext.t (...) WITH (external_location = 'hdfs://nn/user/etl/target_dir');
EXCEPTION
  WHEN presto_error THEN
    -- check path exists/is a directory and permissions, then retry
    ROLLBACK;
END;

Prevention

When it happens

Trigger: 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.

Common situations: 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.


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