apache/iceberg · error · IllegalStateException

Dynamo table is not active, current status

Error message

Dynamo table %s is not active, current status: %s

What it means

IllegalStateException from DynamoDbLockManager.checkTableActive when the Dynamo table used for locking exists but its status is not ACTIVE (e.g. CREATING, UPDATING, DELETING). The lock manager requires a fully active table to perform consistent reads and conditional writes.

Solutions

  1. Wait until describeTable reports status ACTIVE before initializing the lock manager
  2. If the table was just created, retry after provisioning completes (or use a waiter)
  3. Check CloudTrail/console for an in-progress UpdateTable or DeleteTable and wait for it to finish
  4. If the table was deleted unintentionally, recreate it with the expected key schema

Example fix

// before
DynamoDbLockManager lockManager = new DynamoDbLockManager(dynamo, tableName);
// after
TableWaiter waiter = dynamo.waiter();
waiter.waitUntilTableExists(b -> b.tableName(tableName));
DynamoDbLockManager lockManager = new DynamoDbLockManager(dynamo, tableName);
Defensive patterns

Strategy: retry

Validate before calling

TableStatus status = dynamo.describeTable(b -> b.tableName(lockTable)).table().tableStatus();
if (status != TableStatus.ACTIVE) {
  throw new IllegalStateException("Lock table not ready: " + status);
}

Try / catch

try {
  lockManager.acquire(entityId, ownerId);
} catch (IllegalStateException e) {
  // wait for table to become ACTIVE, then retry with backoff
  Thread.sleep(10_000);
  lockManager.acquire(entityId, ownerId);
}

Prevention

When it happens

Trigger: acquire or release calling checkTableActive while the lock table is mid-creation, being updated (throughput change), or being deleted.

Common situations: Client started immediately after table creation before the table finished provisioning; autoscaling update in progress; table being torn down while a worker still runs.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

Thrown at aws/src/main/java/org/apache/iceberg/aws/dynamodb/DynamoDbLockManager.java:156

  }

  @VisibleForTesting
  boolean tableExists(String tableName) {
    try {
      dynamo.describeTable(DescribeTableRequest.builder().tableName(tableName).build());
      return true;
    } catch (ResourceNotFoundException e) {
      return false;
    }
  }

  private void checkTableActive(String tableName) {
    try {
      DescribeTableResponse response =
          dynamo.describeTable(DescribeTableRequest.builder().tableName(tableName).build());
      TableStatus currentStatus = response.table().tableStatus();
      if (!currentStatus.equals(TableStatus.ACTIVE)) {
        throw new IllegalStateException(
            String.format(
                "Dynamo table %s is not active, current status: %s", tableName, currentStatus));
      }
    } catch (ResourceNotFoundException e) {
      throw new IllegalStateException(String.format("Cannot find Dynamo table %s", tableName));
    }
  }

  @Override
  public void initialize(Map<String, String> properties) {
    super.initialize(properties);
    this.dynamo = AwsClientFactories.from(properties).dynamo();
    this.lockTableName = properties.get(CatalogProperties.LOCK_TABLE);
    Preconditions.checkNotNull(lockTableName, "DynamoDB lock table name must not be null");
    ensureLockTableExistsOrCreate();
  }

  @Override

View on GitHub (pinned to 86d9c8fc54)