apache/iceberg · error · UncheckedIOException
Cannot update properties on namespace '%s': ref '%s' is no l
Error message
Cannot update properties on namespace '%s': ref '%s' is no longer valid.
What it means
updateProperties catches NessieReferenceNotFoundException and wraps it in an UncheckedIOException stating 'ref %s is no longer valid', where %s is the catalog's current Nessie reference name. Like error 2210, this means the branch/tag itself was deleted or renamed between resolving the ref and committing the namespace update.
Source
Thrown at nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java:441
return commitBuilder;
});
// always successful, otherwise an exception is thrown
return true;
} catch (NessieReferenceConflictException e) {
Optional<Conflict> conflict =
NessieUtil.extractSingleConflict(e, EnumSet.of(Conflict.ConflictType.KEY_DOES_NOT_EXIST));
if (conflict.isPresent()
&& conflict.get().conflictType() == Conflict.ConflictType.KEY_DOES_NOT_EXIST) {
throw new NoSuchNamespaceException(e, "Namespace does not exist: %s", namespace);
}
throw new UncheckedIOException(
String.format(
"Cannot update properties on namespace '%s': %s", namespace, e.getMessage()),
e);
} catch (NessieContentNotFoundException e) {
throw new NoSuchNamespaceException("Namespace does not exist: %s", namespace);
} catch (NessieReferenceNotFoundException e) {
throw new UncheckedIOException(
String.format(
"Cannot update properties on namespace '%s': ref '%s' is no longer valid.",
namespace, getRef().getName()),
e);
} catch (BaseNessieClientServerException e) {
throw new UncheckedIOException(
String.format("Cannot update namespace '%s': %s", namespace, e.getMessage()), e);
}
}
public void renameTable(TableIdentifier from, TableIdentifier to) {
renameContent(from, to, Content.Type.ICEBERG_TABLE);
}
public void renameView(TableIdentifier from, TableIdentifier to) {
renameContent(from, to, Content.Type.ICEBERG_VIEW);
}
View on GitHub (pinned to 86d9c8fc54)
Solutions
- Recreate the reference (branch/tag) in Nessie or repoint the catalog config to an existing one.
- Re-instantiate the catalog so getRef() resolves the new reference name.
- Add a pre-flight existence check for the ref (Nessie API getAllReferences) in job startup code.
- Exclude active workload branches from automated cleanup policies.
Example fix
// before
conf.set(" NessieCatalog.ref", "pr-123"); // branch already deleted by CI
// after
String ref = refExists(nessieApi, "pr-123") ? "pr-123" : "main";
conf.set("NessieCatalog.ref", ref); Defensive patterns
Strategy: try-catch
Validate before calling
boolean refOk = nessieApi.getAllReferences().get().getReferences()
.stream().anyMatch(r -> r.getName().equals(catalogRef)); Try / catch
try {
catalog.setProperties(ns, props);
} catch (UncheckedIOException e) {
if (String.valueOf(e.getMessage()).contains("no longer valid")) {
throw new RecoverableCatalogException("ref deleted: " + catalogRef, e);
}
throw e;
} Prevention
- Validate the configured ref at job startup, not only at failure time.
- Protect long-running job branches from automated cleanup.
- Reload/rebuild the catalog after ref renames so getRef() resolves fresh.
- Alert on branch deletion events (webhooks) affecting active workloads.
When it happens
Trigger: setProperties/removeProperties while the configured reference (e.g. branch 'main' or a feature branch) was deleted or renamed on the Nessie server; the commit's reference lookup fails server-side.
Common situations: Automated branch cleanup deleting short-lived branches while jobs still run against them; branch renamed in a governance workflow; typo'd or stale ref in catalog configuration discovered only when a write is attempted (reads may still be cached).
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- Cannot load namespace '%s': ref '%s' is no longer valid.
- Cannot update properties on namespace '%s': %s
- Cannot update namespace '%s': %s
- Cannot rename %s '%s' to '%s': ref '%s' no longer exists.
- Namespace already exists: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/eead758b880e6177.
Report an issue: GitHub.