t8y2/dbx · critical · IllegalStateException
H2 JDBC driver was not loaded
Error message
H2 JDBC driver was not loaded
What it means
H2Agent keeps a loaded JDBC driver reference injected at startup. openConnection throws IllegalStateException when that reference is null, meaning no H2 driver was registered/loaded before connecting, so no connection can be established.
Source
Thrown at agents/drivers/h2/src/main/java/com/dbx/agent/h2/H2Agent.java:83
}
private void replaceLoadedDriver(H2DriverLoader.LoadedDriver replacement) throws Exception {
H2DriverLoader.LoadedDriver previous = loadedDriver;
if (previous != null) {
try {
previous.classLoader().close();
} catch (Exception error) {
replacement.classLoader().close();
throw error;
}
}
loadedDriver = replacement;
}
@Override
protected Connection openConnection(ConnectParams params) throws Exception {
if (loadedDriver == null) {
throw new IllegalStateException("H2 JDBC driver was not loaded");
}
Connection opened = loadedDriver.driver().connect(buildJdbcUrl(params), buildConnectionProperties(params));
if (opened == null) {
throw new SQLException("H2 JDBC driver rejected URL: " + buildJdbcUrl(params));
}
return opened;
}
@Override
protected void afterConnect(ConnectParams params, Connection connection) {
databaseName = params.getDatabase();
databaseMajorVersion = unchecked(() -> connection.getMetaData().getDatabaseMajorVersion());
}
H2DriverVersion driverVersion() {
return driverVersion;
}
View on GitHub (pinned to c0390bff16)
Solutions
- Add the H2 JDBC driver dependency (com.h2database:h2) to the classpath
- Ensure the driver loading/initialization hook runs before openConnection
- Verify no shading/classloader isolation hides the driver class
Example fix
// before
Connection c = agent.connect(params); // driver never loaded
// after
Class.forName("org.h2.Driver"); // or call agent's driver-load/init hook
Connection c = agent.connect(params); Defensive patterns
Strategy: validation
Validate before calling
try { Class.forName("org.h2.Driver"); } catch (ClassNotFoundException e) { throw new IllegalStateException("H2 driver missing from classpath; add com.h2database:h2", e); } Type guard
static boolean h2DriverAvailable() { try { Class.forName("org.h2.Driver"); return true; } catch (ClassNotFoundException e) { return false; } } Try / catch
try { conn = agent.connect(params); } catch (IllegalStateException e) { if (e.getMessage().contains("driver was not loaded")) { initDriver(); conn = agent.connect(params); } else throw e; } Prevention
- Add com.h2database:h2 as a runtime dependency
- Ensure driver initialization runs before any connect call
- Check shaded/fat jars actually include org.h2.Driver
- Verify custom classloaders can see the driver class
When it happens
Trigger: openConnection is invoked before the driver was loaded/set (loadedDriver == null), e.g. missing H2 jar on the classpath or driver initialization step skipped.
Common situations: H2 dependency excluded from the build; custom classloader (plugin/app-server) not seeing the driver jar; initialization order calling connect before driver setup; shaded jar missing driver classes.
Related errors
- H2 JDBC driver rejected URL: " + buildJdbcUrl(params)
- JDBC pool registry must be attached before connecting
- Not connected
- JDBC Session was quarantined while waiting for a connection
- Object source is not supported
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/2a7dc272d4a8c0c3.
Report an issue: GitHub.