prestodb/presto · error · TableNotFoundException

failed to retrieve table metadata from ${newLocation}

Error message

failed to retrieve table metadata from ${newLocation}

What it means

After successfully parsing the metadata file, refreshFromMetadataLocation() verifies newMetadata was set; if it is still null (the retry runnable completed without producing metadata) it throws TableNotFoundException 'failed to retrieve table metadata from <newLocation>'. This is the edge case where reading neither threw nor produced content.

Source

Thrown at presto-iceberg/src/main/java/com/facebook/presto/iceberg/HiveTableOperations.java:455

        AtomicReference<TableMetadata> newMetadata = new AtomicReference<>();
        try {
            Tasks.foreach(newLocation)
                    .retry(config.getTableRefreshRetries())
                    .shouldRetryTest(this::shouldRetry)
                    .exponentialBackoff(
                            config.getTableRefreshBackoffMinSleepTime().toMillis(),
                            config.getTableRefreshBackoffMaxSleepTime().toMillis(),
                            config.getTableRefreshMaxRetryTime().toMillis(),
                            config.getTableRefreshBackoffScaleFactor())
                    .run(metadataLocation -> newMetadata.set(
                            TableMetadataParser.read(fileIO, fileIO.newCachedInputFile(metadataLocation))));
        }
        catch (RuntimeException e) {
            throw new TableNotFoundException(getSchemaTableName(), "Table metadata is missing", e);
        }

        if (newMetadata.get() == null) {
            throw new TableNotFoundException(getSchemaTableName(), "failed to retrieve table metadata from " + newLocation);
        }

        String newUUID = newMetadata.get().uuid();
        if (currentMetadata != null) {
            checkState(newUUID == null || newUUID.equals(currentMetadata.uuid()),
                    "Table UUID does not match: current=%s != refreshed=%s", currentMetadata.uuid(), newUUID);
        }

        currentMetadata = newMetadata.get();
        currentMetadataLocation = newLocation;
        version = parseVersion(newLocation);
        shouldRefresh = false;
    }

    private boolean shouldRetry(Exception exception)
    {
        return !(exception.getCause() instanceof FileNotFoundException);
    }

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Inspect the metadata file at the reported location (size/integrity) and repair or restore it from the previous valid metadata version.
  2. Roll the HMS METADATA_LOCATION back to the last known-good metadata JSON if the current one is corrupt.
  3. Clear any file-I/O cache (fileIO.newCachedInputFile) that may have cached the empty response.
  4. Run Iceberg metadata validation/repair tooling (e.g. remove_orphan_files carefully, restore from backups).

Example fix

// before (assume latest is good)
String location = table.parameters().get(METADATA_LOCATION);
// after — verify content before use, else fall back to previous version
byte[] bytes = readAll(location);
if (bytes.length == 0) {
    location = previousMetadataLocation; // from PREVIOUS_METADATA_LOCATION param
}
Defensive patterns

Strategy: fallback

Validate before calling

// verify metadata file size and parseability before trusting it
byte[] b = readAllBytes(metadataLocation); if (b.length == 0) fail("empty metadata file");

Try / catch

try { table.refresh(); }
catch (TableNotFoundException e) { /* fall back to PREVIOUS_METADATA_LOCATION or restore from backup */ }

Prevention

When it happens

Trigger: refresh() where the retry loop returns normally but newMetadata remains unset — practically a corrupted/empty cached input stream or a read that silently returned nothing from the metadata location.

Common situations: Truncated or zero-byte metadata JSON on object storage; caching layer returning empty content; partially failed write that left an invalid metadata file in place.

Related errors


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