Skip to content

ice-rest-catalog perform-maintenance fails when EtcdCatalog contains an empty namespace #206

Description

@nmiakushina

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
Image

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.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions