apache/iceberg · critical · UncheckedIOException

Failed to refresh as ref

Error message

Failed to refresh as ref '%s' is no longer valid.

What it means

NessieViewOperations.doRefresh converts NessieNotFoundException into an UncheckedIOException with this message when the pinned Nessie ref is no longer valid during view metadata refresh. Identical family to the table-side error (errorIndex 2225) but on the view operations path: the view cannot be refreshed because its reference vanished.

Solutions

  1. Check the ref exists via the Nessie API and recreate it if removed.
  2. Reload the view/catalog against an existing ref (setRef or correct catalog properties 'ref'/'asset-ref').
  3. Fix ref-name typos in catalog configuration.
  4. Exclude in-use branches from automated deletion/GC.

Example fix

// before
catalog.setRef("pr-branch"); // deleted by CI
View v = catalog.loadView(TableIdentifier.of("ns", "v"));
// after
catalog.setRef(refExists("pr-branch") ? "pr-branch" : "main");
View v = catalog.loadView(TableIdentifier.of("ns", "v"));
Defensive patterns

Strategy: retry

Validate before calling

nessieApi.ref().refName(refName).get(); // fails fast if ref missing before loading view

Try / catch

try { view.refresh(); } catch (UncheckedIOException e) { if (e.getCause() instanceof NessieNotFoundException) { catalog.setRef("main"); view = catalog.loadView(id); } else { throw e; } }

Prevention

When it happens

Trigger: Any view operation (load/refresh/commit) after the branch/tag backing the catalog was deleted or expired; stale ref after branch cleanup automation; wrong ref name configured.

Common situations: Feature branches deleted by CI while views still loaded on them; ref rename in Nessie not reflected in Spark/Flink catalog config; retention policies pruning active refs.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/3cbb23b7da34c544. Report an issue: GitHub.

Appendix: source

Thrown at nessie/src/main/java/org/apache/iceberg/nessie/NessieViewOperations.java:59

  private static final Logger LOG = LoggerFactory.getLogger(NessieViewOperations.class);

  private final NessieIcebergClient client;
  private final ContentKey key;
  private final FileIO fileIO;
  private IcebergView icebergView;

  NessieViewOperations(ContentKey key, NessieIcebergClient client, FileIO fileIO) {
    this.key = key;
    this.client = client;
    this.fileIO = fileIO;
  }

  @Override
  public void doRefresh() {
    try {
      client.refresh();
    } catch (NessieNotFoundException e) {
      throw new UncheckedIOException(
          String.format(
              "Failed to refresh as ref '%s' is no longer valid.", client.getRef().getName()),
          e);
    }
    String metadataLocation = null;
    Reference reference = client.getRef().getReference();
    try {
      Content content = client.getApi().getContent().key(key).reference(reference).get().get(key);
      LOG.debug("Content '{}' at '{}': {}", key, reference, content);
      if (content == null) {
        if (currentMetadataLocation() != null) {
          throw new NoSuchViewException("View does not exist: %s in %s", key, reference);
        }
      } else {
        this.icebergView =
            content
                .unwrap(IcebergView.class)
                .orElseThrow(() -> new NessieContentNotFoundException(key, reference.getName()));

View on GitHub (pinned to 86d9c8fc54)