Summary
ice-rest-catalog perform-maintenance aborts before processing any table when EtcdCatalog.listNamespaces() returns an empty namespace.
The REST API returns valid namespaces together with an empty namespace:
curl -sSk \
'https://iceberg-catalog-logs.altinity-cloudwatch.dev.altinity.cloud/v1/namespaces' \
-H "Authorization: Bearer ${ICE_TOKEN}" |
jq
{
"namespaces": [
[
""
],
[
"logs"
],
[
"metrics"
]
],
"next-page-token": null
}
logs:
2026-08-10 13:54:13 [main/1] INFO c.a.i.r.c.i.e.EtcdCatalog > Connected to etcd at http://ice-rest-catalog-etcd:2379/
2026-08-10 13:54:13 [main/1] INFO c.a.ice.rest.catalog.Main > Catalog backend: etcd
2026-08-10 13:54:14 [main/1] INFO c.a.i.r.c.i.m.MaintenanceRunner > Performing catalog maintenance
2026-08-10 13:54:14 [main/1] ERROR c.a.ice.rest.catalog.Main > Fatal
org.apache.iceberg.exceptions.ValidationException: Namespace level must not be empty:
at org.apache.iceberg.exceptions.ValidationException.check(ValidationException.java:49)
at com.altinity.ice.rest.catalog.internal.etcd.EtcdCatalog.validateNamespace(EtcdCatalog.java:286)
at com.altinity.ice.rest.catalog.internal.etcd.EtcdCatalog.listTables(EtcdCatalog.java:440)
at com.altinity.ice.rest.catalog.internal.maintenance.MaintenanceRunner.run(MaintenanceRunner.java:38)
at com.altinity.ice.rest.catalog.Main.performMaintenance(Main.java:187)
at com.altinity.ice.rest.catalog.Main.main(Main.java:636) [10 skipped]
MaintenanceRunner subsequently calls EtcdCatalog.listTables() for the empty namespace. EtcdCatalog.validateNamespace() rejects it, causing the entire catalog-wide maintenance run to fail.
This also happens with --dry-run, so no maintenance plan can be inspected.
Version
cr-enam.altinity.io/altinity/ice-rest-catalog:0.16.0
ice-rest-catalog perform-maintenance \
--job=SNAPSHOT_CLEANUP \
--max-snapshot-age-hours=24 \
--min-snapshots-to-keep=500 \
--dry-run
Expected behavior
One of the following:
- listNamespaces() must not return an invalid empty namespace; or
- MaintenanceRunner should validate and skip empty/invalid namespaces; or
- EtcdCatalog.listTables() should handle the root namespace consistently if the empty namespace is intentional.
An invalid namespace should not prevent maintenance of all valid namespaces and tables.
It would also be helpful for catalog-wide maintenance to isolate failures per namespace/table, report them at the end, and continue processing valid tables.
Summary
ice-rest-catalog perform-maintenanceaborts before processing any table whenEtcdCatalog.listNamespaces()returns an empty namespace.The REST API returns valid namespaces together with an empty namespace:
logs:
MaintenanceRunner subsequently calls EtcdCatalog.listTables() for the empty namespace. EtcdCatalog.validateNamespace() rejects it, causing the entire catalog-wide maintenance run to fail.
This also happens with --dry-run, so no maintenance plan can be inspected.
Version
cr-enam.altinity.io/altinity/ice-rest-catalog:0.16.0Expected behavior
One of the following:
An invalid namespace should not prevent maintenance of all valid namespaces and tables.
It would also be helpful for catalog-wide maintenance to isolate failures per namespace/table, report them at the end, and continue processing valid tables.