{"record":{"id":"eead758b880e6177","repo":"apache/iceberg","slug":"cannot-update-properties-on-namespace-s-ref","errorCode":null,"errorMessage":"Cannot update properties on namespace '%s': ref '%s' is no longer valid.","messagePattern":"Cannot update properties on namespace '(.+?)': ref '(.+?)' is no longer valid\\.","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":500,"severity":"error","filePath":"nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java","lineNumber":441,"sourceCode":"            return commitBuilder;\n          });\n      // always successful, otherwise an exception is thrown\n      return true;\n    } catch (NessieReferenceConflictException e) {\n      Optional<Conflict> conflict =\n          NessieUtil.extractSingleConflict(e, EnumSet.of(Conflict.ConflictType.KEY_DOES_NOT_EXIST));\n      if (conflict.isPresent()\n          && conflict.get().conflictType() == Conflict.ConflictType.KEY_DOES_NOT_EXIST) {\n        throw new NoSuchNamespaceException(e, \"Namespace does not exist: %s\", namespace);\n      }\n      throw new UncheckedIOException(\n          String.format(\n              \"Cannot update properties on namespace '%s': %s\", namespace, e.getMessage()),\n          e);\n    } catch (NessieContentNotFoundException e) {\n      throw new NoSuchNamespaceException(\"Namespace does not exist: %s\", namespace);\n    } catch (NessieReferenceNotFoundException e) {\n      throw new UncheckedIOException(\n          String.format(\n              \"Cannot update properties on namespace '%s': ref '%s' is no longer valid.\",\n              namespace, getRef().getName()),\n          e);\n    } catch (BaseNessieClientServerException e) {\n      throw new UncheckedIOException(\n          String.format(\"Cannot update namespace '%s': %s\", namespace, e.getMessage()), e);\n    }\n  }\n\n  public void renameTable(TableIdentifier from, TableIdentifier to) {\n    renameContent(from, to, Content.Type.ICEBERG_TABLE);\n  }\n\n  public void renameView(TableIdentifier from, TableIdentifier to) {\n    renameContent(from, to, Content.Type.ICEBERG_VIEW);\n  }\n","sourceCodeStart":423,"sourceCodeEnd":459,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java#L423-L459","documentation":"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.","triggerScenarios":"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.","commonSituations":"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).","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."],"exampleFix":"// before\nconf.set(\" NessieCatalog.ref\", \"pr-123\"); // branch already deleted by CI\n// after\nString ref = refExists(nessieApi, \"pr-123\") ? \"pr-123\" : \"main\";\nconf.set(\"NessieCatalog.ref\", ref);","handlingStrategy":"try-catch","validationCode":"boolean refOk = nessieApi.getAllReferences().get().getReferences()\n    .stream().anyMatch(r -> r.getName().equals(catalogRef));","typeGuard":null,"tryCatchPattern":"try {\n  catalog.setProperties(ns, props);\n} catch (UncheckedIOException e) {\n  if (String.valueOf(e.getMessage()).contains(\"no longer valid\")) {\n    throw new RecoverableCatalogException(\"ref deleted: \" + catalogRef, e);\n  }\n  throw e;\n}","preventionTips":["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."],"tags":["nessie","catalog","namespace","reference-not-found","configuration"],"backgroundTag":"resource-not-found","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}