apache/iceberg · error · UncheckedSQLException

Unknown failure

Error message

Unknown failure

What it means

JdbcViewOperations.doCommit wraps any SQLException that is not a timeout, connection failure, data truncation, warning, or constraint violation into an UncheckedSQLException with the generic message 'Unknown failure'. This is the catch-all for unexpected database errors during a JDBC catalog view commit, preserving the underlying SQLException as the cause.

Source

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

    } catch (SQLTimeoutException e) {
      throw new UncheckedSQLException(e, "Database Connection timeout");
    } catch (SQLTransientConnectionException | SQLNonTransientConnectionException e) {
      throw new UncheckedSQLException(e, "Database Connection failed");
    } catch (DataTruncation e) {
      throw new UncheckedSQLException(e, "Database data truncation error");
    } catch (SQLWarning e) {
      throw new UncheckedSQLException(e, "Database warning");
    } catch (SQLException e) {
      if (JdbcUtil.isConstraintViolation(e)) {
        if (currentMetadataLocation() == null) {
          throw new AlreadyExistsException(e, "View already exists: %s", viewIdentifier);
        } else {
          throw new UncheckedSQLException(e, "View already exists: %s", viewIdentifier);
        }
      }

      throw new UncheckedSQLException(e, "Unknown failure");
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      throw new UncheckedInterruptedException(e, "Interrupted during commit");
    }
  }

  @Override
  protected String viewName() {
    return viewIdentifier.toString();
  }

  @Override
  protected FileIO io() {
    return fileIO;
  }

  private void validateMetadataLocation(Map<String, String> view, ViewMetadata base) {
    String catalogMetadataLocation = view.get(JdbcTableOperations.METADATA_LOCATION_PROP);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Read the wrapped SQLException cause (e.getCause()) to identify the real database error; the message itself is intentionally generic
  2. Verify the JDBC catalog database schema matches the Iceberg version (iceberg_views/iceberg_tables tables and columns exist)
  3. Check the DB user has SELECT/INSERT/UPDATE privileges on the catalog tables
  4. Test basic connectivity and query the catalog tables directly with the same JDBC URL and credentials
  5. Retry the commit if the error was transient (connection drop); otherwise fix the underlying DB issue before retrying

Example fix

// before: opaque failure
try {
  viewOps.commit(...);
} catch (UncheckedSQLException e) {
  LOG.error("commit failed: {}", e.getMessage()); // "Unknown failure"
}
// after: surface the real cause
try {
  viewOps.commit(...);
} catch (UncheckedSQLException e) {
  LOG.error("view commit failed", e.getCause()); // actual SQLException
}
Defensive patterns

Strategy: try-catch

Validate before calling

// check DB reachability & privileges before committing
try (Connection c = dataSource.getConnection()) {
  try (Statement s = c.createStatement()) {
    s.executeQuery("SELECT 1 FROM iceberg_views LIMIT 1"); // table exists & readable
  }
}

Try / catch

try {
  viewOps.commit(request);
} catch (UncheckedSQLException e) {
  SQLException cause = e.getCause();
  LOG.error("View commit failed for {}", viewId, cause); // inspect real SQL error
  if (isTransient(cause)) retryWithBackoff();
}

Prevention

When it happens

Trigger: Committing a view through a JDBC catalog when the database raises an unexpected SQLException — e.g. schema mismatch in the iceberg_views table, table missing (SQLSyntaxErrorException), lock wait timeout, permission denied on UPDATE/INSERT, or connection dropped mid-statement with an unmapped SQLState.

Common situations: Deploying against a JDBC catalog whose backing database schema was created by an older Iceberg version (missing view columns); DB user lacking DML privileges on catalog tables; network interruption between driver and database; DB-specific errors like MySQL 'Lock wait timeout exceeded' or Postgres 'relation does not exist'.

Related errors


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