apache/iceberg · error · UncheckedSQLException

Cannot check and eventually update SQL schema

Error message

Cannot check and eventually update SQL schema

What it means

Generic wrap-up thrown by JdbcCatalog.updateSchemaIfRequired for any SQLException that isn't a timeout or connection failure while checking/updating the catalog's SQL schema. The catalog determines the stored schema version and may run a V0→V1 migration; any other database error aborts initialization with this message.

Source

Thrown at core/src/main/java/org/apache/iceberg/jdbc/JdbcCatalog.java:267

                        JdbcUtil.SchemaVersion.V0.name())
                    .equalsIgnoreCase(JdbcUtil.SchemaVersion.V1.name())) {
                  LOG.debug(
                      "{} is being updated to support views", JdbcUtil.CATALOG_TABLE_VIEW_NAME);
                  schemaVersion = JdbcUtil.SchemaVersion.V1;
                  return executeV1CatalogUpdate(conn);
                } else {
                  LOG.warn(VIEW_WARNING_LOG_MESSAGE);
                  return true;
                }
              }
            }
          });
    } catch (SQLTimeoutException e) {
      throw new UncheckedSQLException(e, "Cannot update JDBC catalog: Query timed out");
    } catch (SQLTransientConnectionException | SQLNonTransientConnectionException e) {
      throw new UncheckedSQLException(e, "Cannot update JDBC catalog: Connection failed");
    } catch (SQLException e) {
      throw new UncheckedSQLException(e, "Cannot check and eventually update SQL schema");
    } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      throw new UncheckedInterruptedException(e, "Interrupted in call to initialize");
    }
  }

  private static boolean executeV1CatalogUpdate(Connection conn) throws SQLException {
    try (PreparedStatement stmt = conn.prepareStatement(JdbcUtil.V1_UPDATE_CATALOG_SQL)) {
      return stmt.execute();
    }
  }

  @Override
  protected TableOperations newTableOps(TableIdentifier tableIdentifier) {
    return new JdbcTableOperations(
        connections, io, catalogName, tableIdentifier, catalogProperties, schemaVersion);
  }

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Inspect the wrapped SQLException cause for the exact database error
  2. Ensure the DB user can ALTER TABLE on the catalog tables (needed for V0→V1 auto-migration)
  3. Set jdbc.schema-version explicitly (V0 or V1) to match the actual database state
  4. Restore the catalog tables to the expected schema (e.g. via the official DDL) if they were manually modified

Example fix

// before
props.put("jdbc.schema-version", "V1"); // DB is still V0 and user cannot ALTER
// after
props.put("jdbc.schema-version", "V0"); // or grant ALTER on iceberg_catalog, then use V1
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure DB user can ALTER catalog tables before enabling V1 auto-migration
// check actual schema state:
// SELECT * FROM iceberg_catalog LIMIT 1; -- confirm expected columns exist

Try / catch

try {
  catalog.initialize(name);
} catch (UncheckedSQLException e) {
  throw new RuntimeException("JDBC catalog schema check failed; see cause", e.getCause());
}

Prevention

When it happens

Trigger: initialize() fails because the schema-check statement errors — e.g. the catalog tables exist with an unexpected structure, the DB user lacks privileges to ALTER TABLE during a V0→V1 migration, or a syntax/feature error from an unsupported database.

Common situations: A catalog database created by an older Iceberg version with a foreign/modified schema, a read-only DB account trying to auto-migrate, or manually altered iceberg_catalog tables that no longer match the expected DDL.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


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