{"record":{"id":"a99a9aa0215c7c94","repo":"flowable/flowable-engine","slug":"could-not-find-a-datasource-for-tenant-tenantid","errorCode":null,"errorMessage":"Could not find a dataSource for tenant ${tenantId}","messagePattern":"Could not find a dataSource for tenant (.+?)","errorType":"exception","errorClass":"org.flowable.common.engine.api.FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/cfg/multitenant/TenantAwareDataSource.java","lineNumber":68,"sourceCode":"    public void removeDataSource(Object key) {\n        dataSources.remove(key);\n    }\n\n    @Override\n    public Connection getConnection() throws SQLException {\n        return getCurrentDataSource().getConnection();\n    }\n\n    @Override\n    public Connection getConnection(String username, String password) throws SQLException {\n        return getCurrentDataSource().getConnection(username, password);\n    }\n\n    protected DataSource getCurrentDataSource() {\n        String tenantId = tenantInfoHolder.getCurrentTenantId();\n        DataSource dataSource = dataSources.get(tenantId);\n        if (dataSource == null) {\n            throw new FlowableException(\"Could not find a dataSource for tenant \" + tenantId);\n        }\n        return dataSource;\n    }\n\n    @Override\n    public int getLoginTimeout() throws SQLException {\n        return 0; // Default\n    }\n\n    @Override\n    public Logger getParentLogger() throws SQLFeatureNotSupportedException {\n        return Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    @Override\n    public <T> T unwrap(Class<T> iface) throws SQLException {\n        if (iface.isInstance(this)) {","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/cfg/multitenant/TenantAwareDataSource.java#L50-L86","documentation":"TenantAwareDataSource routes JDBC connections per tenant using a map of tenantId -> DataSource. When getConnection() asks for the current tenant's DataSource and it was never registered, Flowable throws this FlowableException. It means the tenant is unknown to the data source registry, not that the database is unreachable.","triggerScenarios":"Calling getConnection() on TenantAwareDataSource while TenantInfoHolder.getCurrentTenantId() returns a tenantId that has no entry in the dataSources map (never added via addDataSource).","commonSituations":"Tenant id typo or case mismatch between request context and registered tenants; new tenant provisioned in app but addDataSource() never called; tenantInfoHolder not populated correctly (e.g. defaulting to an unexpected tenant id); multi-tenant engine started before all tenant datasources registered.","solutions":["Call dataSources (TenantAwareDataSource.addDataSource) for the tenant before any connection is requested","Log TenantInfoHolder.getCurrentTenantId() at request time and compare it against the registered tenant keys (watch case/whitespace)","Add a provisioning step that registers each tenant's DataSource at startup or on tenant creation","Provide a default/fallback tenant id in your TenantInfoHolder implementation for unknown tenants"],"exampleFix":"// before\nTenantAwareDataSource ds = new TenantAwareDataSource(tenantInfoHolder);\nds.addDataSource(\"acme\", acmeDs); // tenant resolves to \"ACME\"\n// after\nds.addDataSource(\"acme\", acmeDs);\nds.addDataSource(\"ACME\", acmeDs); // or normalize tenant ids in TenantInfoHolder","handlingStrategy":"validation","validationCode":"String tenantId = tenantInfoHolder.getCurrentTenantId();\nif (!tenantAwareDataSources.contains(tenantId)) { // track registered ids yourself\n    throw new IllegalStateException(\"No DataSource registered for tenant \" + tenantId);\n}","typeGuard":null,"tryCatchPattern":"try (Connection c = tenantAwareDs.getConnection()) {\n    // use connection\n} catch (FlowableException e) {\n    if (e.getMessage() != null && e.getMessage().startsWith(\"Could not find a dataSource for tenant\")) {\n        // register the missing tenant or fail fast with a clear provisioning error\n    }\n}","preventionTips":["Register every tenant's DataSource via addDataSource() before serving requests","Normalize tenant ids (case, whitespace) in TenantInfoHolder before lookup","Log the current tenant id on connection acquisition during development","Add a startup check that all configured tenants have a registered DataSource"],"tags":["datasource","multi-tenant","configuration","flowable"],"backgroundTag":"resource-not-found","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}