t8y2/dbx · error · IOException
Custom H2 JDBC JAR does not exist: " + path
Error message
Custom H2 JDBC JAR does not exist: " + path
What it means
loadExternal validates each configured JAR path: it resolves to an absolute normalized Path and requires it to be a regular file. A configured path that does not exist (or is a directory) causes this IOException so the loader never builds a class loader over bogus URLs.
Source
Thrown at agents/drivers/h2/src/main/java/com/dbx/agent/h2/H2DriverLoader.java:51
} catch (Exception error) {
closeAfterFailure(classLoader, error);
throw error;
} catch (LinkageError error) {
closeAfterFailure(classLoader, error);
throw error;
}
}
static LoadedDriver loadExternal(List<String> driverPaths, String driverClass) throws Exception {
if (driverPaths == null || driverPaths.isEmpty()) {
throw new IllegalArgumentException("Custom H2 driver profile requires at least one JDBC JAR path");
}
List<URL> urls = new ArrayList<>();
List<String> identities = new ArrayList<>();
for (String driverPath : driverPaths) {
Path path = Path.of(driverPath).toAbsolutePath().normalize();
if (!Files.isRegularFile(path)) {
throw new IOException("Custom H2 JDBC JAR does not exist: " + path);
}
urls.add(path.toUri().toURL());
identities.add(path + ":" + sha256(path));
}
String effectiveDriverClass = driverClass == null || driverClass.isBlank() ? "org.h2.Driver" : driverClass.trim();
URLClassLoader classLoader = new URLClassLoader(
urls.toArray(new URL[0]),
H2DriverLoader.class.getClassLoader()
);
try {
Driver driver = (Driver) Class.forName(effectiveDriverClass, true, classLoader).getDeclaredConstructor().newInstance();
return new LoadedDriver(H2DriverVersion.CUSTOM, effectiveDriverClass + "|" + String.join("|", identities), driver, classLoader);
} catch (Exception error) {
closeAfterFailure(classLoader, error);
throw error;
} catch (LinkageError error) {
closeAfterFailure(classLoader, error);
throw error;View on GitHub (pinned to c0390bff16)
Solutions
- Correct the configured path to point at an existing JDBC JAR file (verify with ls / Files.exists)
- Copy the H2 JAR to the expected location before starting the agent
- Use an absolute path in configuration so it does not depend on the process working directory
Example fix
// before
H2DriverLoader.loadExternal(List.of("/opt/drivers/h2.jar"), null); // file deleted
// after
H2DriverLoader.loadExternal(List.of("/opt/drivers/h2-2.2.224.jar"), null); // file present Defensive patterns
Strategy: validation
Validate before calling
List<String> valid = driverPaths.stream()
.filter(p -> Files.isRegularFile(Path.of(p).toAbsolutePath().normalize()))
.toList();
if (valid.size() != driverPaths.size()) throw new IllegalStateException("missing JAR(s)"); Try / catch
try {
return H2DriverLoader.loadExternal(driverPaths, driverClass);
} catch (IOException e) {
logger.error("Configured H2 JAR missing: {}", e.getMessage());
throw new ConfigurationException(e);
} Prevention
- Use absolute paths for driver JARs in configuration
- Check Files.exists for each path during application startup health checks
- Pin JARs to a dedicated drivers directory excluded from cleanup jobs
When it happens
Trigger: Calling loadExternal with a driverPaths entry pointing to a nonexistent file, a deleted/moved JAR, or a directory path.
Common situations: JAR deleted by cleanup job or upgrade script; relative path resolved from a different working directory; typo in the configured path; JAR is on a not-yet-mounted volume.
Related errors
- H2 MVStore file is too small to contain valid headers: " + f
- Custom H2 driver profile requires at least one JDBC JAR path
- Bundled H2 driver is missing: " + version.resourcePath()
- Both H2 PageStore and MVStore files exist for " + base + ";
- H2 JDBC driver was not loaded
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/645c5b9ea77ab269.
Report an issue: GitHub.