apache/iceberg · error · UncheckedIOException
Failed to create tableMaintenance
Error message
Failed to create tableMaintenance
What it means
IcebergSink.addPostCommitTopology builds the table maintenance (expire snapshots/rewrite data files) operator; an IOException during its construction is wrapped as UncheckedIOException with this message. It means the post-commit maintenance topology could not be initialized, typically because the table cannot be read from the loader.
Source
Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/sink/IcebergSink.java:305
} else {
builder = TableMaintenance.forChangeStream(tableChangeStream, tableLoader);
}
builder
.uidSuffix(tableMaintenanceUid)
.add(maintenanceTasks)
.rateLimit(Duration.ofSeconds(flinkMaintenanceConfig.rateLimit()))
.lockCheckDelay(Duration.ofSeconds(flinkMaintenanceConfig.lockCheckDelay()))
.parallelism(flinkMaintenanceConfig.parallelism());
String slotSharingGroup = flinkMaintenanceConfig.slotSharingGroup();
if (slotSharingGroup != null) {
builder.slotSharingGroup(slotSharingGroup);
}
builder.append();
} catch (IOException e) {
throw new UncheckedIOException("Failed to create tableMaintenance ", e);
}
}
@Override
public DataStream<RowData> addPreWriteTopology(DataStream<RowData> inputDataStream) {
return distributeDataStream(inputDataStream);
}
@Override
public DataStream<CommittableMessage<IcebergCommittable>> addPreCommitTopology(
DataStream<CommittableMessage<WriteResult>> writeResults) {
TypeInformation<CommittableMessage<IcebergCommittable>> typeInformation =
CommittableMessageTypeInfo.of(this::getCommittableSerializer);
String suffix = defaultSuffix(uidSuffix, table.name());
String preCommitAggregatorUid = String.format("Sink pre-commit aggregator: %s", suffix);
// global forces all output records send to subtask 0 of the downstream committer operator.View on GitHub (pinned to 86d9c8fc54)
Solutions
- Inspect the wrapped cause for the underlying IO failure (path missing, auth, timeout).
- Verify the table exists and TableLoader config is valid from the cluster.
- Ensure filesystem/catalog credentials are available to the JobManager; retry submission after the storage issue resolves.
Example fix
// before: maintenance on missing table
IcebergSink.forRowData(input).table(table).tableLoader(loader).append();
// after: validate first
if (!catalog.tableExists(tableId)) throw new IllegalStateException("table missing");
IcebergSink.forRowData(input).table(catalog.loadTable(tableId)).tableLoader(loader).append(); Defensive patterns
Strategy: validation
Validate before calling
// validate table access and maintenance prerequisites before enabling maintenance
try (TableLoader loader = tableLoader) {
loader.open();
Table t = loader.loadTable();
Preconditions.checkArgument(catalog.tableExists(tableId), "table missing: %s", tableId);
} Try / catch
try {
sink.append();
} catch (UncheckedIOException e) {
if (e.getMessage().startsWith("Failed to create tableMaintenance")) {
logger.error("maintenance init failed", e.getCause());
}
throw e;
} Prevention
- Verify table/catalog reachability from the JobManager before enabling maintenance.
- Disable maintenance (don't set maintenance properties) until storage issues are resolved.
- Monitor metastore/HDFS health in deployment checks.
When it happens
Trigger: Calling .append() on an IcebergSink builder with maintenance enabled when the maintenance builder's table access throws IOException — table metadata unreadable, catalog/warehouse unreachable, or credentials missing on the JobManager.
Common situations: HDFS/S3 outage at job startup; kerberos/HMS auth not configured; table deleted between submit and run; misconfigured maintenance properties pointing at missing resources.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Failed to create tableMaintenance
- Failed to create tableMaintenance
- Failed to create tableMaintenance
- Failed to list partitions of table %s
- Failed to check the state of the lock %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/1290f8511d5360f8.
Report an issue: GitHub.