apache/iceberg · error · UncheckedSQLException

Cannot update JDBC catalog: Connection failed

Error message

Cannot update JDBC catalog: Connection failed

What it means

Thrown by JdbcCatalog.updateSchemaIfRequired when the JDBC connection to the catalog database fails transiently or non-transiently (SQLTransientConnectionException / SQLNonTransientConnectionException) while checking or updating the catalog schema. It means the catalog could not reach or hold a connection during initialize().

Source

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

                        catalogProperties,
                        JdbcUtil.SCHEMA_VERSION_PROPERTY,
                        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. Verify the uri, jdbc.user, and jdbc.password properties and that the database is reachable (test with psql/mysql client)
  2. Check the database server is running and accepting connections on the configured host/port
  3. Check connection pool limits and max_connections on the server
  4. Inspect the wrapped SQLException cause for the precise driver-level failure and fix accordingly

Example fix

// before
props.put("uri", "jdbc:postgresql://db-prod:5432/iceberg"); // host unreachable from app network
// after
props.put("uri", "jdbc:postgresql://localhost:5432/iceberg"); // or fix network/credentials first
Defensive patterns

Strategy: retry

Validate before calling

try (Connection c = DriverManager.getConnection(uri, user, pass)) {
  // proves reachability + credentials before catalog init
  c.createStatement().execute("SELECT 1");
}

Type guard

boolean credentialsValid(String uri, String user, String pass) {
  try (Connection c = DriverManager.getConnection(uri, user, pass)) { return true; }
  catch (SQLException e) { return false; }
}

Try / catch

try {
  catalog.initialize(name);
} catch (UncheckedSQLException e) {
  if (e.getMessage().contains("Connection failed")) {
    retryWithBackoff(5, Duration.ofSeconds(2)); // tolerate transient DB unavailability
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling initialize() when the database is unreachable, the credentials are wrong, the connection pool is exhausted, TLS handshake fails, or the DB closes the connection mid-run during the schema-version check/migration.

Common situations: Database container not yet started (startup race), wrong jdbc.user/jdbc.password, max connections exhausted by other clients, firewall/security-group blocks, or DB restart during catalog initialization.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


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