Activiti/Activiti · error · ActivitiException
couldn't db schema
Error message
couldn't ${operation} db schema: ${exceptionSqlStatement} What it means
Generic wrapper for failures while executing a schema script (create/drop/upgrade/check) in executeSchemaResource: the SQL statement recorded in exceptionSqlStatement failed, so the whole '<operation> db schema' is aborted with an ActivitiException carrying the failing statement. It signals the database rejected a DDL/DML statement during schema management.
Solutions
- Read the failing statement in the message and the underlying SQLException cause to see the DB error.
- If tables already exist / partial state, either drop the old ACT_* tables or set databaseSchemaUpdate=false and manage schema manually.
- Grant the DB user DDL privileges (CREATE, ALTER, DROP) needed by the schema scripts.
- Confirm databaseType detection is correct (jdbc url/driver) so the right dialect scripts run.
- Run schema scripts manually with your DB tool to get better diagnostics, then start the engine with schema update disabled.
Example fix
// before processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); // after (create schema manually via SQL scripts, then) processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE);
Defensive patterns
Strategy: try-catch
Try / catch
try {
processEngine = cfg.buildProcessEngine();
} catch (ActivitiException e) {
if (e.getMessage() != null && e.getMessage().startsWith("couldn't ") && e.getMessage().contains("db schema:")) {
log.error("Schema op failed on statement: {} | cause: {}", e.getMessage(), e.getCause(), e);
}
throw e;
} Prevention
- Ensure the DB user has CREATE/ALTER/DROP privileges.
- Don't point databaseSchemaUpdate=true at a partially created schema; clean or manage schema manually.
- Verify databaseType detection matches your actual database.
- Execute schema scripts manually with your DB tool for clearer diagnostics.
When it happens
Trigger: Engine startup with databaseSchemaUpdate=true (or explicit schema create/drop) executes the SQL statements of a schema resource; one statement throws a SQLException, caught by executeSchemaResource's catch block, and 'couldn't <operation> db schema: <sql>' is thrown.
Common situations: Tables already exist (partial prior create) causing 'table already exists' on create; insufficient DB user privileges for CREATE TABLE/ALTER; DB type mismatched so dialect-specific SQL fails; reserved keyword or type incompatibilities on unusual DB versions.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
Related errors
- Activiti database problem
- Could not retrieve database metadata
- Could not set database schema on connection
- couldn't get activiti table names using metadata
- no activiti tables in db. set <property…
AI-assisted analysis of Activiti/Activiti@56435b1a97 (2026-09-09).
Data as JSON: /api/errors/871ecb8add1ab27a.
Report an issue: GitHub.
Appendix: source
Thrown at activiti-core/activiti-engine/src/main/java/org/activiti/engine/impl/db/DbSqlSession.java:1286
log.error("problem during schema {}, statement {}", operation, sqlStatement, e);
} finally {
sqlStatement = null;
}
} else {
sqlStatement = addSqlStatementPiece(sqlStatement, line);
}
}
line = readNextTrimmedLine(reader);
}
if (exception != null) {
throw exception;
}
log.debug("activiti db schema {} for component {} successful", operation, component);
} catch (Exception e) {
throw new ActivitiException("couldn't " + operation + " db schema: " + exceptionSqlStatement, e);
}
}
/**
* MySQL is funny when it comes to timestamps and dates.
* <p>
* More specifically, for a DDL statement like 'MYCOLUMN timestamp(3)': - MySQL 5.6.4+ has support for timestamps/dates with millisecond (or smaller) precision. The DDL above works and the data in
* the table will have millisecond precision - MySQL < 5.5.3 allows the DDL statement, but ignores it. The DDL above works but the data won't have millisecond precision - MySQL 5.5.3 < [version] <
* 5.6.4 gives and exception when using the DDL above.
* <p>
* Also, the 5.5 and 5.6 branches of MySQL are both actively developed and patched.
* <p>
* Hence, when doing auto-upgrade/creation of the Activiti tables, the default MySQL DDL file is used and all timestamps/datetimes are converted to not use the millisecond precision by string
* replacement done in the method below.
* <p>
* If using the DDL files directly (which is a sane choice in production env.), there is a distinction between MySQL version < 5.6.
*/
protected String updateDdlForMySqlVersionLowerThan56(String ddlStatements) {View on GitHub (pinned to 56435b1a97)