{"record":{"id":"b396cb99b2e09184","repo":"quarkusio/quarkus","slug":"no-instance-of-datasource-found-for-persistence-un","errorCode":null,"errorMessage":"No instance of datasource found for persistence unit '%1$s' and tenant '%2$s'","messagePattern":"No instance of datasource found for persistence unit '%1\\$s' and tenant '%2\\$s'","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/tenant/DataSourceTenantConnectionResolver.java","lineNumber":52,"sourceCode":"\n    public DataSourceTenantConnectionResolver() {\n    }\n\n    public DataSourceTenantConnectionResolver(String persistenceUnitName, Optional<String> dataSourceName,\n            MultiTenancyStrategy multiTenancyStrategy) {\n        this.persistenceUnitName = persistenceUnitName;\n        this.dataSourceName = dataSourceName;\n        this.multiTenancyStrategy = multiTenancyStrategy;\n    }\n\n    @Override\n    public ConnectionProvider resolve(String tenantId) {\n        LOG.debugv(\"resolve((persistenceUnitName={0}, tenantIdentifier={1})\", persistenceUnitName, tenantId);\n        LOG.debugv(\"multitenancy strategy: {0}\", multiTenancyStrategy);\n\n        AgroalDataSource dataSource = tenantDataSource(dataSourceName, tenantId, multiTenancyStrategy);\n        if (dataSource == null) {\n            throw new IllegalStateException(\n                    String.format(Locale.ROOT, \"No instance of datasource found for persistence unit '%1$s' and tenant '%2$s'\",\n                            persistenceUnitName, tenantId));\n        }\n        return switch (multiTenancyStrategy) {\n            case DATABASE -> new QuarkusConnectionProvider(dataSource);\n            case SCHEMA -> new SchemaTenantConnectionProvider(tenantId, dataSource);\n            default -> throw new IllegalStateException(\"Unexpected multitenancy strategy: \" + multiTenancyStrategy);\n        };\n    }\n\n    private static AgroalDataSource tenantDataSource(Optional<String> dataSourceName, String tenantId,\n            MultiTenancyStrategy strategy) {\n        return switch (strategy) {\n            case DATABASE -> Arc.container().instance(AgroalDataSource.class, new DataSource.DataSourceLiteral(tenantId)).get();\n            // The datasource name should always be present when using a multi-tenancy other than DATABASE;\n            // we perform checks in HibernateOrmProcessor during the build.\n            case SCHEMA -> getDataSource(dataSourceName.get());\n            default -> throw new IllegalStateException(\"Unexpected multitenancy strategy: \" + strategy);","sourceCodeStart":34,"sourceCodeEnd":70,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/tenant/DataSourceTenantConnectionResolver.java#L34-L70","documentation":"The multitenant Hibernate connection resolver could not find an Agroal datasource matching the given persistence unit and tenant id, so it cannot build a ConnectionProvider. It throws IllegalStateException naming both the PU and tenant.","triggerScenarios":"At runtime on tenant resolution: the datasource named for the tenant (or per-strategy lookup) doesn't exist — wrong quarkus.datasource.<name> config, datasource not defined for a DATABASE-strategy tenant id, tenant id mismatch (case/typos) with a configured datasource name, or multiTenancyStrategy CONFIGURATION without matching datasource beans.","commonSituations":"Missing quarkus.datasource.\"tenant1\".jdbc.url config; TenantResolver producing tenant ids that don't match datasource names; renaming datasources without updating the tenant mapping; using SCHEMA strategy without the required named datasource configured.","solutions":["Define the missing datasource in application.properties, e.g. quarkus.datasource.\"<tenantId>\".jdbc.url=...","Make TenantResolver.resolveTenantId() return ids that exactly match configured datasource names","Verify the persistence unit's datasource name (quarkus.hibernate-orm.datasource) and strategy configuration align with the tenant datasources","Check build-time validation config for multitenancy (quarkus.hibernate-orm.multitenant) matches the strategy used"],"exampleFix":"// before: TenantResolver returns \"acme\" but no datasource named acme\n// after (application.properties)\nquarkus.datasource.\"acme\".db-kind=postgresql\nquarkus.datasource.\"acme\".jdbc.url=jdbc:postgresql://localhost:5432/acme\nquarkus.datasource.\"acme\".username=user\nquarkus.datasource.\"acme\".password=pass","handlingStrategy":"validation","validationCode":"AgroalDataSource ds = Arc.container().instance(AgroalDataSource.class,\n        AgroalDataSourceUtil.qualifier(tenantId)).get();\nif (ds == null) {\n    throw new IllegalStateException(\"No datasource configured for tenant \" + tenantId\n        + \" — check quarkus.datasource.\\\"\" + tenantId + \"\\\".*\");\n}","typeGuard":"Optional<AgroalDataSource> lookupTenantDs(String tenantId) {\n    return Optional.ofNullable(Arc.container().instance(AgroalDataSource.class,\n        AgroalDataSourceUtil.qualifier(tenantId)).get());\n}","tryCatchPattern":"try {\n    ConnectionProvider cp = resolver.resolve(tenantId);\n} catch (IllegalStateException e) {\n    Log.errorf(\"Datasource missing for PU=%s tenant=%s\", pu, tenantId);\n    throw new WebApplicationException(\"Unknown tenant\", 400);\n}","preventionTips":["Define one quarkus.datasource.\"<tenantId>\" block per tenant","Keep TenantResolver tenant ids in sync with datasource names (add an automated test)","Validate multitenancy config at startup with a smoke resolution of all tenants"],"tags":["multitenancy","datasource","agroal","config"],"backgroundTag":"missing-datasource-for-tenant","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}