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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions