flowable/flowable-engine · error · org.flowable.common.engine.api.FlowableException

Could not find a dataSource for tenant ${tenantId}

Error message

Could not find a dataSource for tenant ${tenantId}

What it means

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.

Source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/cfg/multitenant/TenantAwareDataSource.java:68

    public void removeDataSource(Object key) {
        dataSources.remove(key);
    }

    @Override
    public Connection getConnection() throws SQLException {
        return getCurrentDataSource().getConnection();
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return getCurrentDataSource().getConnection(username, password);
    }

    protected DataSource getCurrentDataSource() {
        String tenantId = tenantInfoHolder.getCurrentTenantId();
        DataSource dataSource = dataSources.get(tenantId);
        if (dataSource == null) {
            throw new FlowableException("Could not find a dataSource for tenant " + tenantId);
        }
        return dataSource;
    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0; // Default
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
    }

    @SuppressWarnings("unchecked")
    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        if (iface.isInstance(this)) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Call dataSources (TenantAwareDataSource.addDataSource) for the tenant before any connection is requested
  2. Log TenantInfoHolder.getCurrentTenantId() at request time and compare it against the registered tenant keys (watch case/whitespace)
  3. Add a provisioning step that registers each tenant's DataSource at startup or on tenant creation
  4. Provide a default/fallback tenant id in your TenantInfoHolder implementation for unknown tenants

Example fix

// before
TenantAwareDataSource ds = new TenantAwareDataSource(tenantInfoHolder);
ds.addDataSource("acme", acmeDs); // tenant resolves to "ACME"
// after
ds.addDataSource("acme", acmeDs);
ds.addDataSource("ACME", acmeDs); // or normalize tenant ids in TenantInfoHolder
Defensive patterns

Strategy: validation

Validate before calling

String tenantId = tenantInfoHolder.getCurrentTenantId();
if (!tenantAwareDataSources.contains(tenantId)) { // track registered ids yourself
    throw new IllegalStateException("No DataSource registered for tenant " + tenantId);
}

Try / catch

try (Connection c = tenantAwareDs.getConnection()) {
    // use connection
} catch (FlowableException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Could not find a dataSource for tenant")) {
        // register the missing tenant or fail fast with a clear provisioning error
    }
}

Prevention

When it happens

Trigger: Calling getConnection() on TenantAwareDataSource while TenantInfoHolder.getCurrentTenantId() returns a tenantId that has no entry in the dataSources map (never added via addDataSource).

Common situations: 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.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/a99a9aa0215c7c94. Report an issue: GitHub.