{"record":{"id":"213588fab69367e5","repo":"apache/iceberg","slug":"failed-to-refresh-as-ref-s-is-no-longer-valid","errorCode":null,"errorMessage":"Failed to refresh as ref '%s' is no longer valid.","messagePattern":"Failed to refresh as ref '(.+?)' is no longer valid\\.","errorType":"exception","errorClass":"UncheckedIOException","httpStatus":500,"severity":"critical","filePath":"nessie/src/main/java/org/apache/iceberg/nessie/NessieTableOperations.java","lineNumber":74,"sourceCode":"\n  /** Create a nessie table operations given a table identifier. */\n  NessieTableOperations(ContentKey key, NessieIcebergClient client, FileIO fileIO) {\n    this.key = key;\n    this.client = client;\n    this.fileIO = fileIO;\n  }\n\n  @Override\n  protected String tableName() {\n    return key.toString();\n  }\n\n  @Override\n  protected void doRefresh() {\n    try {\n      client.refresh();\n    } catch (NessieNotFoundException e) {\n      throw new UncheckedIOException(\n          String.format(\n              \"Failed to refresh as ref '%s' is no longer valid.\", client.getRef().getName()),\n          e);\n    }\n    String metadataLocation = null;\n    Reference reference = client.getRef().getReference();\n    try {\n      Content content = client.getApi().getContent().key(key).reference(reference).get().get(key);\n      LOG.debug(\"Content '{}' at '{}': {}\", key, reference, content);\n      if (content == null) {\n        if (currentMetadataLocation() != null) {\n          throw new NoSuchTableException(\"No such table '%s' in '%s'\", key, reference);\n        }\n      } else {\n        this.table =\n            content\n                .unwrap(IcebergTable.class)\n                .orElseThrow(() -> new NessieContentNotFoundException(key, reference.getName()));","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/nessie/src/main/java/org/apache/iceberg/nessie/NessieTableOperations.java#L56-L92","documentation":"NessieTableOperations.doRefresh wraps NessieNotFoundException (raised when the ref/hash the client is pinned to no longer exists) into an UncheckedIOException with this message. It means the Nessie reference used by the table's operations was deleted or expired between operations, so the table metadata cannot be refreshed.","triggerScenarios":"Calling any table operation (load, refresh, read, commit) after the Nessie branch/tag the catalog was opened against was deleted, e.g. via branch cleanup or Nessie GC; also stale refs after namespace branch pruning.","commonSituations":"CI pipelines deleting ephemeral branches while a long-running Spark job still holds the ref; wrong ref name in catalog config after a rename; Nessie retention pruning live refs.","solutions":["Verify the ref still exists (Nessie API: GET /trees/{ref}) and recreate it if deleted.","Reload the table/catalog against an existing ref so operations are re-pinned.","Check catalog 'ref'/'asset-ref' config for typos or stale values.","Ensure branch-deletion automation doesn't remove refs still in use by running jobs."],"exampleFix":"// before\nNessieCatalog catalog = ... configured with ref \"etl-feature\"; // branch deleted\ncatalog.loadTable(TableIdentifier.of(\"ns\", \"t\")); // UncheckedIOException\n// after\nNessieCatalog catalog = ...;\nif (catalog.getRef().getReference().getName().equals(\"etl-feature\") && !nessieRefExists(\"etl-feature\")) {\n  catalog.setRef(\"main\");\n}\nTable t = catalog.loadTable(TableIdentifier.of(\"ns\", \"t\"));","handlingStrategy":"retry","validationCode":"Reference r = nessieApi.ref().refName(refName).get(); // throws NessieNotFoundException if gone","typeGuard":null,"tryCatchPattern":"try { table.refresh(); } catch (UncheckedIOException e) { if (e.getCause() instanceof NessieNotFoundException) { catalog.setRef(\"main\"); table = catalog.loadTable(id); } else { throw e; } }","preventionTips":["Verify branch existence before long jobs and after failures","Exclude in-use branches from CI cleanup and Nessie GC/retention policies","Reload table operations instead of retrying on the same dead ref"],"tags":["nessie","ref-not-found","refresh","branch-deleted","unchecked-io"],"backgroundTag":"entity-not-found","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}