{"record":{"id":"07247979964c1083","repo":"apache/iceberg","slug":"cannot-update-jdbc-catalog-connection-failed","errorCode":null,"errorMessage":"Cannot update JDBC catalog: Connection failed","messagePattern":"Cannot update JDBC catalog: Connection failed","errorType":"exception","errorClass":"UncheckedSQLException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/apache/iceberg/jdbc/JdbcCatalog.java","lineNumber":265,"sourceCode":"                        catalogProperties,\n                        JdbcUtil.SCHEMA_VERSION_PROPERTY,\n                        JdbcUtil.SchemaVersion.V0.name())\n                    .equalsIgnoreCase(JdbcUtil.SchemaVersion.V1.name())) {\n                  LOG.debug(\n                      \"{} is being updated to support views\", JdbcUtil.CATALOG_TABLE_VIEW_NAME);\n                  schemaVersion = JdbcUtil.SchemaVersion.V1;\n                  return executeV1CatalogUpdate(conn);\n                } else {\n                  LOG.warn(VIEW_WARNING_LOG_MESSAGE);\n                  return true;\n                }\n              }\n            }\n          });\n    } catch (SQLTimeoutException e) {\n      throw new UncheckedSQLException(e, \"Cannot update JDBC catalog: Query timed out\");\n    } catch (SQLTransientConnectionException | SQLNonTransientConnectionException e) {\n      throw new UncheckedSQLException(e, \"Cannot update JDBC catalog: Connection failed\");\n    } catch (SQLException e) {\n      throw new UncheckedSQLException(e, \"Cannot check and eventually update SQL schema\");\n    } catch (InterruptedException e) {\n      Thread.currentThread().interrupt();\n      throw new UncheckedInterruptedException(e, \"Interrupted in call to initialize\");\n    }\n  }\n\n  private static boolean executeV1CatalogUpdate(Connection conn) throws SQLException {\n    try (PreparedStatement stmt = conn.prepareStatement(JdbcUtil.V1_UPDATE_CATALOG_SQL)) {\n      return stmt.execute();\n    }\n  }\n\n  @Override\n  protected TableOperations newTableOps(TableIdentifier tableIdentifier) {\n    return new JdbcTableOperations(\n        connections, io, catalogName, tableIdentifier, catalogProperties, schemaVersion);","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/apache/iceberg/blob/86d9c8fc543e7c56c9f624eb725f76c9baff9570/core/src/main/java/org/apache/iceberg/jdbc/JdbcCatalog.java#L247-L283","documentation":"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().","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify the uri, jdbc.user, and jdbc.password properties and that the database is reachable (test with psql/mysql client)","Check the database server is running and accepting connections on the configured host/port","Check connection pool limits and max_connections on the server","Inspect the wrapped SQLException cause for the precise driver-level failure and fix accordingly"],"exampleFix":"// before\nprops.put(\"uri\", \"jdbc:postgresql://db-prod:5432/iceberg\"); // host unreachable from app network\n// after\nprops.put(\"uri\", \"jdbc:postgresql://localhost:5432/iceberg\"); // or fix network/credentials first","handlingStrategy":"retry","validationCode":"try (Connection c = DriverManager.getConnection(uri, user, pass)) {\n  // proves reachability + credentials before catalog init\n  c.createStatement().execute(\"SELECT 1\");\n}","typeGuard":"boolean credentialsValid(String uri, String user, String pass) {\n  try (Connection c = DriverManager.getConnection(uri, user, pass)) { return true; }\n  catch (SQLException e) { return false; }\n}","tryCatchPattern":"try {\n  catalog.initialize(name);\n} catch (UncheckedSQLException e) {\n  if (e.getMessage().contains(\"Connection failed\")) {\n    retryWithBackoff(5, Duration.ofSeconds(2)); // tolerate transient DB unavailability\n  } else { throw e; }\n}","preventionTips":["Validate uri/jdbc.user/jdbc.password with a direct JDBC connection test before loadCatalog","Ensure the database is started and reachable on the network (firewall/security groups)","Keep pool sizes below the server's max_connections","Use retry with backoff around catalog initialization for transient outages"],"tags":["jdbc","database","connection","network"],"backgroundTag":"connection-refused","analyzedSha":"86d9c8fc543e7c56c9f624eb725f76c9baff9570","analyzedAt":"2026-09-12T00:46:39.097Z","contentChangedAt":"2026-09-12T00:46:39.097Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}