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

  1. Add the H2 JDBC driver dependency (com.h2database:h2) to the classpath
  2. Ensure the driver loading/initialization hook runs before openConnection
  3. 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

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


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/2a7dc272d4a8c0c3. Report an issue: GitHub.