apache/iceberg · error · NoSuchViewException

View does not exist: %s

Error message

View does not exist: %s

What it means

NoSuchViewException raised by JdbcViewOperations.doRefresh when the catalog returns no row for the view but the operations object already holds a current metadata location. This is an inconsistent-state signal: the view this handle was previously reading has been dropped underneath it. If no metadata location is cached, refresh simply disables instead (a fresh handle for a not-yet-created view).

Source

Thrown at core/src/main/java/org/apache/iceberg/jdbc/JdbcViewOperations.java:83

  @Override
  protected void doRefresh() {
    Map<String, String> view;

    try {
      view = JdbcUtil.loadView(JdbcUtil.SchemaVersion.V1, connections, catalogName, viewIdentifier);
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      throw new UncheckedInterruptedException(e, "Interrupted during refresh");
    } catch (SQLException e) {
      // SQL exception happened when getting view from catalog
      throw new UncheckedSQLException(
          e, "Failed to get view %s from catalog %s", viewIdentifier, catalogName);
    }

    if (view.isEmpty()) {
      if (currentMetadataLocation() != null) {
        throw new NoSuchViewException("View does not exist: %s", viewIdentifier);
      } else {
        this.disableRefresh();
        return;
      }
    }

    String newMetadataLocation = view.get(JdbcTableOperations.METADATA_LOCATION_PROP);
    Preconditions.checkState(
        newMetadataLocation != null, "Invalid view %s: metadata location is null", viewIdentifier);
    refreshFromMetadataLocation(newMetadataLocation);
  }

  @Override
  protected void doCommit(ViewMetadata base, ViewMetadata metadata) {
    String newMetadataLocation = writeNewMetadataIfRequired(metadata);
    try {
      Map<String, String> view =
          JdbcUtil.loadView(JdbcUtil.SchemaVersion.V1, connections, catalogName, viewIdentifier);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Re-acquire the view via catalog.loadView to get a fresh handle, checking existence first
  2. Coordinate DROP VIEW with concurrent readers/writers (application-level locking or retry logic)
  3. Verify the view wasn't dropped by another job or manual DB cleanup
  4. If the drop was unintentional, restore the catalog row and metadata file from backup

Example fix

// before
View view = catalog.loadView(ident); // NoSuchViewException if dropped concurrently
// after
if (catalog.viewExists(ident)) {
  View view = catalog.loadView(ident);
} else {
  // handle dropped view: recreate or skip
}
Defensive patterns

Strategy: validation

Validate before calling

boolean exists = catalog.viewExists(ident);
if (!exists) {
  // handle missing view before loading/committing
}

Try / catch

try {
  View view = catalog.loadView(ident);
} catch (NoSuchViewException e) {
  // view was dropped concurrently; recreate or skip
}

Prevention

When it happens

Trigger: Reading or committing a view after another process dropped it from the JDBC catalog (DELETE on iceberg_views) while this JdbcViewOperations instance still references the old metadata location.

Common situations: Concurrent DROP VIEW on another session/cluster sharing the same JDBC catalog; stale handles after catalog maintenance or manual row deletion.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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