{"record":{"id":"9440f6e0c079407d","repo":"apache/iceberg","slug":"cannot-update-properties-on-namespace-s-s","errorCode":null,"errorMessage":"Cannot update properties on namespace '%s': %s","messagePattern":"Cannot update properties on namespace '(.+?)': (.+?)","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":500,"severity":"error","filePath":"nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java","lineNumber":434,"sourceCode":"            action.accept(newProperties);\n            org.projectnessie.model.Namespace updatedNamespace =\n                org.projectnessie.model.Namespace.builder()\n                    .from(oldNamespace)\n                    .properties(newProperties)\n                    .build();\n            commitBuilder.operation(Operation.Put.of(key, updatedNamespace));\n            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) {","sourceCodeStart":416,"sourceCodeEnd":452,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java#L416-L452","documentation":"updateProperties commits a namespace-objects Put via commitRetry; when the commit fails with NessieReferenceConflictException that is NOT the benign KEY_DOES_NOT_EXIST conflict, the client wraps it in an UncheckedIOException 'Cannot update properties on namespace ... : <server message>'. This signals a merge-style conflict on the ref (content changed concurrently) that Iceberg surfaces as a generic IO failure.","triggerScenarios":"setProperties/removeProperties where another commit concurrently modified the same namespace key (or another conflicting key) on the branch, producing a reference conflict other than KEY_DOES_NOT_EXIST; the conflict cannot be attributed to a missing namespace.","commonSituations":"Two writers updating the same namespace properties simultaneously; a rebase/merge on the Nessie branch introducing conflicts; namespace object changed by a different tool (e.g. Spark vs Flink jobs) between read and commit.","solutions":["Retry the setProperties/removeProperties call — updateProperties already retries via commitRetry, but persistent conflicts require re-running after the other writer finishes.","Serialize namespace property updates through a single writer or use a mutable branch dedicated to metadata changes.","Inspect the embedded server conflict message (e.getMessage()) to identify the conflicting key and coordinate with the other writer.","If conflicts are frequent, switch the workload to write to per-job branches and merge deliberately."],"exampleFix":"// before\ncatalog.setProperties(ns, props); // UncheckedIOException on concurrent conflict\n// after\ntry {\n  catalog.setProperties(ns, props);\n} catch (UncheckedIOException e) {\n  // transient concurrent-modification conflict; back off and retry\n  Thread.sleep(1000);\n  catalog.setProperties(ns, props);\n}","handlingStrategy":"retry","validationCode":"boolean busy = recentWritersOn(namespace); // your own coordination/lock mechanism\nif (busy) { waitUntilFree(namespace); }","typeGuard":null,"tryCatchPattern":"int attempts = 3;\nwhile (attempts-- > 0) {\n  try { catalog.setProperties(ns, props); break; }\n  catch (UncheckedIOException e) {\n    if (attempts == 0 || !isConflictMessage(e)) throw e;\n    sleep(backoff);\n  }\n}","preventionTips":["Single-writer discipline for namespace property updates.","Add retry with exponential backoff around property mutations.","Avoid rebasing/merging into a branch while metadata writers are active.","Use dedicated metadata branches if multiple tools mutate namespaces."],"tags":["nessie","catalog","namespace","conflict","concurrency"],"backgroundTag":"invalid-state-transition","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"}