apache/iceberg · error · NoSuchTableException
No such table '%s'
Error message
No such table '%s'
What it means
In NessieTableOperations.doRefresh, if getContent itself throws NessieNotFoundException and the table had already been loaded, the code rethrows it as NoSuchTableException('No such table %s'). This differs from 2226 in that the failure came from the Nessie API call (e.g. the reference or hash was not found during content fetch), not from a null content result.
Source
Thrown at nessie/src/main/java/org/apache/iceberg/nessie/NessieTableOperations.java:97
String metadataLocation = null;
Reference reference = client.getRef().getReference();
try {
Content content = client.getApi().getContent().key(key).reference(reference).get().get(key);
LOG.debug("Content '{}' at '{}': {}", key, reference, content);
if (content == null) {
if (currentMetadataLocation() != null) {
throw new NoSuchTableException("No such table '%s' in '%s'", key, reference);
}
} else {
this.table =
content
.unwrap(IcebergTable.class)
.orElseThrow(() -> new NessieContentNotFoundException(key, reference.getName()));
metadataLocation = table.getMetadataLocation();
}
} catch (NessieNotFoundException ex) {
if (currentMetadataLocation() != null) {
throw new NoSuchTableException(ex, "No such table '%s'", key);
}
}
refreshFromMetadataLocation(
metadataLocation,
null,
2,
location ->
NessieUtil.updateTableMetadataWithNessieSpecificProperties(
TableMetadataParser.read(fileIO, location),
location,
table,
key.toString(),
reference));
}
@Override
protected void doCommit(TableMetadata base, TableMetadata metadata) {
boolean newTable = base == null;View on GitHub (pinned to 86d9c8fc54)
Solutions
- Re-acquire the table through a catalog bound to a live ref.
- Verify the ref exists and recreate/re-pin it if deleted (catalog.setRef or fix config).
- Catch NoSuchTableException (with cause NessieNotFoundException) in callers and reload rather than retrying blindly.
- Avoid deleting branches/refs that active jobs reference.
Example fix
// before
try { table.refresh(); } catch (RuntimeException e) { /* may be this NoSuchTableException */ }
// after
try {
table.refresh();
} catch (NoSuchTableException e) {
table = catalog.loadTable(id); // re-resolve against a live ref
} Defensive patterns
Strategy: try-catch
Validate before calling
try { nessieApi.content().key(key).reference(ref).get(); } catch (NessieNotFoundException e) { /* ref gone; re-resolve */ } Try / catch
try { table.refresh(); } catch (NoSuchTableException e) { if (e.getCause() instanceof NessieNotFoundException) { table = catalog.loadTable(key); } else { throw e; } } Prevention
- Re-resolve catalog/table when NessieNotFoundException appears as cause
- Avoid deleting refs used by running scans
- Monitor Nessie branch lifecycle from job orchestration
When it happens
Trigger: Content fetch against a ref that is deleted/expired mid-refresh while the table is already loaded; concurrent branch deletion during a read; hash-specific lookups after ref rewind.
Common situations: Ephemeral branch removed while a Spark/Flink job is mid-scan; Nessie GC pruning; ref switched underneath a long-running operation.
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
- Table does not exist: %s
- No such table '%s' in '%s'
- Cannot find Glue table %s after refresh, maybe another proce
- Table does not exist: %s
- Nessie ref '%s' does not exist
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/74ab94936475b16d.
Report an issue: GitHub.