prestodb/presto · error · PrestoException
ICEBERG_INVALID_SPEC_ID
ICEBERG_INVALID_SPEC_ID
Error message
Given spec id does not exist: %s
What it means
RewriteManifestsProcedure accepts an optional specId parameter identifying which partition spec's manifests to rewrite. Before using it, the procedure verifies the id exists in the Iceberg table's specs() map. If not, it throws ICEBERG_INVALID_SPEC_ID because rewriting manifests against a non-existent spec would corrupt manifest metadata.
Source
Thrown at presto-iceberg/src/main/java/com/facebook/presto/iceberg/procedure/RewriteManifestsProcedure.java:82
"rewrite_manifests",
ImmutableList.of(
new Argument("schema", VARCHAR),
new Argument("table_name", VARCHAR),
new Argument("spec_id", INTEGER, false, null)),
REWRITE_MANIFESTS.bindTo(this));
}
public void rewriteManifests(ConnectorSession clientSession, String schemaName, String tableName, Integer specId)
{
try (ThreadContextClassLoader ignored = new ThreadContextClassLoader(getClass().getClassLoader())) {
SchemaTableName schemaTableName = new SchemaTableName(schemaName, tableName);
IcebergAbstractMetadata metadata = (IcebergAbstractMetadata) metadataFactory.create();
Table icebergTable = getIcebergTable(metadata, clientSession, schemaTableName);
RewriteManifests rewriteManifests = icebergTable.rewriteManifests().clusterBy(file -> "file");
int targetSpecId;
if (specId != null) {
if (!icebergTable.specs().containsKey(specId)) {
throw new PrestoException(ICEBERG_INVALID_SPEC_ID, "Given spec id does not exist: " + specId);
}
targetSpecId = specId;
}
else {
targetSpecId = icebergTable.spec().specId();
}
rewriteManifests.rewriteIf(manifest -> manifest.partitionSpecId() == targetSpecId).commit();
metadata.commit();
}
}
}
View on GitHub (pinned to 55bb57d202)
Solutions
- List the table's current spec ids (e.g. inspect the table metadata / specs) and pass an existing one
- Omit the spec_id argument so the procedure defaults to the table's current spec (icebergTable.spec().specId())
- If the spec was intentionally removed, rewrite manifests without spec_id and let Iceberg handle legacy specs
Example fix
// before CALL system.rewrite_manifests(table => 'db.t', spec_id => 7); -- spec 7 no longer exists // after CALL system.rewrite_manifests(table => 'db.t'); -- uses current spec
Defensive patterns
Strategy: validation
Validate before calling
int specId = ...;
if (!icebergTable.specs().containsKey(specId)) {
throw new IllegalArgumentException("Unknown spec id: " + specId +
"; known ids: " + icebergTable.specs().keySet());
} Type guard
boolean isValidSpecId(Table icebergTable, int specId) {
return icebergTable.specs().containsKey(specId);
} Try / catch
try {
runRewriteManifests(specId);
} catch (PrestoException e) {
if (ICEBERG_INVALID_SPEC_ID.equals(e.getErrorCode())) {
// fall back to the table's current spec id
runRewriteManifests(null);
}
} Prevention
- Prefer omitting spec_id so the current spec is used automatically
- Re-read spec ids after any partition-spec change (ALTER TABLE SET PROPERTIES)
- Do not hard-code spec ids across environments or table versions
When it happens
Trigger: CALL system.rewrite_manifests with spec_id => <n> where <n> is not a spec id of the target table — typically a stale or guessed id after the table's partition spec evolved (ids are monotonically assigned per spec change).
Common situations: Hard-coded spec_id from an earlier table version that was replaced via ALTER TABLE SET PROPERTIES; confusing spec_id with partition values or spec field ids; copying a spec id from a different table.
Related errors
- NOT_SUPPORTED
- Schema %s not found
- Not a Hive table:
- Not an Iceberg table: ${getSchemaTableName()}
- Table not found: ${new SchemaTableName(database, tableName)}
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/f16e294d0f8ffeed.
Report an issue: GitHub.