apache/iceberg · error · NoSuchTableException

Cannot find table after refresh, maybe another process…

Error message

Cannot find table %s after refresh, maybe another process deleted it or revoked your access permission

What it means

NoSuchTableException thrown in DynamoDbTableOperations.doRefresh when the table item is gone from the Dynamo catalog table but the client previously knew a metadata location. The table existed when this Table was opened but has since disappeared, so refresh cannot proceed.

Solutions

  1. Re-create the table or re-open it via a fresh catalog.loadTable after confirming it should exist
  2. Coordinate with whoever dropped the table; check CloudTrail/audit logs for DeleteItem on the catalog table
  3. Ensure only one admin pipeline manages table lifecycle to avoid concurrent drops

Example fix

// before
Table t = catalog.loadTable(id);
t.refresh(); // fails if table was dropped
// after
Table t;
try {
  t = catalog.loadTable(id);
  t.refresh();
} catch (NoSuchTableException e) {
  t = catalog.createTable(id, schema); // recreate or handle absence
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!catalog.tableExists(tableIdentifier)) {
  // table gone; recreate or reroute before loadTable/refresh
}

Try / catch

try {
  table.refresh();
} catch (NoSuchTableException e) {
  LOG.warn("Table {} was deleted externally", table.name());
  // recreate or fail the job gracefully
}

Prevention

When it happens

Trigger: Refreshing a table whose Dynamo item was deleted between commit/refresh cycles while currentMetadataLocation() != null.

Common situations: Another process or user ran dropTable concurrently; IAM permissions were revoked so the GetItem returns no item is not the case here (it would throw) — rather the item was genuinely removed; environment sharing the same Dynamo table with an admin cleaning it up.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/31aa237462d9bb96. Report an issue: GitHub.

Appendix: source

Thrown at aws/src/main/java/org/apache/iceberg/aws/dynamodb/DynamoDbTableOperations.java:94

  public FileIO io() {
    return fileIO;
  }

  @Override
  protected void doRefresh() {
    String metadataLocation = null;
    GetItemResponse table =
        dynamo.getItem(
            GetItemRequest.builder()
                .tableName(awsProperties.dynamoDbTableName())
                .consistentRead(true)
                .key(DynamoDbCatalog.tablePrimaryKey(tableIdentifier))
                .build());
    if (table.hasItem()) {
      metadataLocation = getMetadataLocation(table);
    } else {
      if (currentMetadataLocation() != null) {
        throw new NoSuchTableException(
            "Cannot find table %s after refresh, "
                + "maybe another process deleted it or revoked your access permission",
            tableName());
      }
    }

    refreshFromMetadataLocation(metadataLocation);
  }

  @Override
  protected void doCommit(TableMetadata base, TableMetadata metadata) {
    boolean newTable = base == null;
    String newMetadataLocation = writeNewMetadataIfRequired(newTable, metadata);
    CommitStatus commitStatus = CommitStatus.FAILURE;
    RetryDetector retryDetector = new RetryDetector();
    Map<String, AttributeValue> tableKey = DynamoDbCatalog.tablePrimaryKey(tableIdentifier);
    try {
      GetItemResponse table =

View on GitHub (pinned to 86d9c8fc54)