flowable/flowable-engine · error · ActivitiException
couldn't get db schema version
Error message
couldn't get db schema version
What it means
The final fallback in dbSchemaCheckVersion(): if the caught exception during the schema check is neither a missing-tables error nor a RuntimeException, it is wrapped in this ActivitiException ('couldn't get db schema version') with the original as cause. It means the version check failed for an unexpected reason — typically connectivity or driver issues — rather than missing tables.
Solutions
- Inspect the wrapped cause (e.getCause()) for the real failure — usually a SQLException with connection/permission details.
- Verify the JDBC URL, credentials, and that the database is reachable (test with a plain SQL client from the same host).
- Confirm the correct JDBC driver jar is on the classpath and matches the DB server version.
- Grant the DB user rights to read the ACT_GE_PROPERTY table (or create the schema if it doesn't exist via databaseSchemaUpdate=true).
Example fix
// before: wrong credentials, cause hidden
<property name="jdbcUrl" value="jdbc:h2:tcp://localhost/act"/>
<property name="jdbcPassword" value="wrong"/>
// after: fix creds; check cause via logs
<property name="jdbcPassword" value="sa"/>
log.debug("schema check failed", e.getCause()); Defensive patterns
Strategy: try-catch
Validate before calling
// Verify DB connectivity before engine bootstrap
try (Connection c = DriverManager.getConnection(jdbcUrl, user, pass)) {
if (!c.isValid(5)) throw new IllegalStateException("Cannot connect to database");
} Try / catch
try {
ProcessEngines.buildProcessEngine();
} catch (ActivitiException e) {
if ("couldn't get db schema version".equals(e.getMessage()) && e.getCause() != null) {
log.error("Schema check failed: {}", e.getCause().getMessage(), e.getCause());
}
throw e;
} Prevention
- Always inspect the cause chain of this wrapper — the root SQLException names the real problem.
- Pre-flight DB connectivity and credentials in deployment scripts before engine startup.
- Ensure the JDBC driver jar is on the classpath and compatible with the DB server version.
When it happens
Trigger: getDbVersion() or table-presence checks throw a checked/non-runtime exception, e.g. SQLException wrapped as non-runtime, driver class issues, connection failures, or catalog/permission problems that don't match the missing-tables signature.
Common situations: Database unreachable or credentials wrong at engine bootstrap; missing/incorrect JDBC driver on the classpath; network/firewall drops; DB user lacking permission to query ACT_GE_PROPERTY.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- Flowable IDM database problem
- no activiti tables in db. set <property…
- Activiti database problem
- Could not set database schema on connection
- Could not update Flowable database schema: unknown version…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/26fd6020aec8fc57.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/db/DbSqlSession.java:953
}
if (dbSqlSessionFactory.isDbHistoryUsed() && !isHistoryTablePresent()) {
errorMessage = addMissingComponent(errorMessage, "history");
}
if (errorMessage != null) {
throw new ActivitiException("Activiti database problem: " + errorMessage);
}
} catch (Exception e) {
if (isMissingTablesException(e)) {
throw new ActivitiException(
"no activiti tables in db. set <property name=\"databaseSchemaUpdate\" to value=\"true\" or value=\"create-drop\" (use create-drop for testing only!) in bean processEngineConfiguration in flowable.cfg.xml for automatic schema creation",
e);
} else {
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else {
throw new ActivitiException("couldn't get db schema version", e);
}
}
}
LOGGER.debug("activiti db schema check successful");
}
protected String addMissingComponent(String missingComponents, String component) {
if (missingComponents == null) {
return "Tables missing for component(s) " + component;
}
return missingComponents + ", " + component;
}
protected String getDbVersion() {
String selectSchemaVersionStatement = dbSqlSessionFactory.mapStatement("selectDbSchemaVersion");
return (String) sqlSession.selectOne(selectSchemaVersionStatement);
}View on GitHub (pinned to d6d39ce1c6)