{"record":{"id":"02b876aa2c9daa87","repo":"apache/iceberg","slug":"cannot-rename-s-s-to-s-ref-s-no-longer","errorCode":null,"errorMessage":"Cannot rename %s '%s' to '%s': ref '%s' no longer exists.","messagePattern":"Cannot rename (.+?) '(.+?)' to '(.+?)': ref '(.+?)' no longer exists\\.","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":500,"severity":"error","filePath":"nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java","lineNumber":483,"sourceCode":"\n    IcebergContent existingToContent = fetchContent(to);\n    validateToContentForRename(from, to, existingToContent);\n\n    String contentType = NessieUtil.contentTypeString(type).toLowerCase(Locale.ROOT);\n    try {\n      commitRetry(\n          String.format(\"Iceberg rename %s from '%s' to '%s'\", contentType, from, to),\n          Operation.Delete.of(NessieUtil.toKey(from)),\n          Operation.Put.of(NessieUtil.toKey(to), existingFromContent));\n    } catch (NessieNotFoundException e) {\n      // important note: the NotFoundException refers to the ref only. If a table was not found it\n      // would imply that the\n      // another commit has deleted the table from underneath us. This would arise as a Conflict\n      // exception as opposed to\n      // a not found exception. This is analogous to a merge conflict in git when a table has been\n      // changed by one user\n      // and removed by another.\n      throw new UncheckedIOException(\n          String.format(\n              \"Cannot rename %s '%s' to '%s': ref '%s' no longer exists.\",\n              contentType, from, to, getRef().getName()),\n          e);\n    } catch (BaseNessieClientServerException e) {\n      CommitFailedException commitFailedException =\n          new CommitFailedException(\n              e,\n              \"Cannot rename %s '%s' to '%s': the current reference is not up to date.\",\n              contentType,\n              from,\n              to);\n      Optional<RuntimeException> exception = Optional.empty();\n      if (e instanceof NessieConflictException) {\n        exception = NessieUtil.handleExceptionsForCommits(e, getRef().getName(), type);\n      }\n      throw exception.orElse(commitFailedException);\n    } catch (HttpClientException ex) {","sourceCodeStart":465,"sourceCodeEnd":501,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/nessie/src/main/java/org/apache/iceberg/nessie/NessieIcebergClient.java#L465-L501","documentation":"renameContent (backing renameTable/renameView) commits a Delete+Put pair; if the commit fails with NessieNotFoundException, the client explains that the exception refers to the reference, not the content: the ref '%s' no longer exists. The rename is aborted with an UncheckedIOException.","triggerScenarios":"Calling catalog.renameTable(from, to) or renameView while the catalog's configured branch/tag is deleted server-side; commitRetry's commit call receives NessieNotFoundException for the missing ref.","commonSituations":"CI pipelines deleting ephemeral branches while a rename job is still running; someone force-deleted/recreated the branch; catalog cached a ref name that was later renamed; misconfigured ref name that only appears valid due to earlier cached reads.","solutions":["Recreate the missing branch/tag (e.g. from its last known hash or from 'main') and rerun the rename.","Recreate the catalog against a valid reference and retry renameTable/renameView.","Check whether your rename job races with branch lifecycle automation and reorder or protect the branch.","Validate ref existence before starting the rename workflow (getAllReferences pre-flight)."],"exampleFix":"// before\nnessieApi.deleteBranch().branchName(\"etl\").delete(); // job on 'etl' still renaming\ncatalog.renameTable(t1, t2); // fails: ref 'etl' no longer exists\n// after\n// wait for jobs to finish / reassign them to 'main' before deleting branches\nnessieApi.deleteBranch().branchName(\"etl\").delete();","handlingStrategy":"try-catch","validationCode":"boolean refOk = nessieApi.getAllReferences().get().getReferences()\n    .stream().anyMatch(r -> r.getName().equals(catalogRef));\nif (!refOk) { throw new AbortException(\"ref \" + catalogRef + \" missing; skip rename\"); }","typeGuard":null,"tryCatchPattern":"try {\n  catalog.renameTable(from, to);\n} catch (UncheckedIOException e) {\n  if (String.valueOf(e.getMessage()).contains(\"no longer exists\")) {\n    recreateRefThen(() -> catalog.renameTable(from, to));\n  } else throw e;\n}","preventionTips":["Sequence branch deletion after dependent rename/migration jobs complete.","Pre-flight ref existence check before rename workflows.","Never delete-and-recreate a branch while jobs hold a catalog on it; use new branch names.","Track branch lifecycle with webhooks to pause workloads before deletion."],"tags":["nessie","catalog","rename","reference-not-found","concurrency"],"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"}