quarkusio/quarkus · error · ConfigurationException

Persistence unit '%s' is contributed by an extension but is

Error message

Persistence unit '%s' is contributed by an extension but is also configured by the application. A persistence unit contributed through the SPI must use a name that is not already configured through Quarkus configuration or a persistence.xml file.

What it means

When an extension contributes a persistence unit through the SPI, its name must be unique and must not collide with any persistence unit the application already defines through Quarkus configuration or a persistence.xml file. HibernateOrmProcessor throws a ConfigurationException when the contributed name is found among the user-configured persistence unit names.

Source

Thrown at extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/HibernateOrmProcessor.java:447

            Capabilities capabilities,
            BuildProducer<PersistenceUnitDescriptorBuildItem> persistenceUnitDescriptors,
            List<DefaultDataSourceDbVersionBuildItem> defaultDbVersions) {
        // TODO move this validation to a dedicated method, preferably very early in the build?
        //   See also a conceptually similar check in contributeQuarkusConfigToJpaModel
        if (!additionalPersistenceUnits.isEmpty()) {
            Set<String> userConfiguredPersistenceUnitNames = new HashSet<>(hibernateOrmConfig.namedPersistenceUnits().keySet());
            for (PersistenceXmlDescriptorBuildItem persistenceXmlDescriptor : persistenceXmlDescriptors) {
                userConfiguredPersistenceUnitNames.add(persistenceXmlDescriptor.getDescriptor().getName());
            }
            for (AdditionalPersistenceUnitBuildItem additionalPersistenceUnit : additionalPersistenceUnits) {
                String persistenceUnitName = additionalPersistenceUnit.getPersistenceUnitName();
                if (PersistenceUnitUtil.isDefaultPersistenceUnit(persistenceUnitName)) {
                    throw new ConfigurationException(
                            "An extension attempted to contribute the default persistence unit through the SPI."
                                    + " Contributed persistence units must use a non-default name.");
                }
                if (userConfiguredPersistenceUnitNames.contains(persistenceUnitName)) {
                    throw new ConfigurationException(String.format(Locale.ROOT,
                            "Persistence unit '%s' is contributed by an extension but is also configured by the application."
                                    + " A persistence unit contributed through the SPI must use a name that is not already"
                                    + " configured through Quarkus configuration or a persistence.xml file.",
                            persistenceUnitName));
                }
            }
        }

        // Produce the PUs having a persistence.xml: these are not reactive, as we don't allow using a persistence.xml for them.
        for (PersistenceXmlDescriptorBuildItem persistenceXmlDescriptorBuildItem : persistenceXmlDescriptors) {
            PersistenceUnitDescriptor xmlDescriptor = persistenceXmlDescriptorBuildItem.getDescriptor();
            String puName = xmlDescriptor.getName();
            Optional<JdbcDataSourceBuildItem> jdbcDataSource = findDefaultDataSource(jdbcDataSources);
            var model = jpaModel.getModelPerPersistenceUnit().get(puName);
            if (model == null) {
                model = new JpaPersistenceUnitModel();
            }
            collectDialectConfigForPersistenceXml(puName, xmlDescriptor, defaultDbVersions);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Rename the extension-contributed persistence unit to a name not used in persistence.xml or quarkus.hibernate-orm config
  2. Remove or rename the application-side persistence unit with the conflicting name

Example fix

// application.properties
# before
quarkus.hibernate-orm."audit".datasource=audit-ds
// after
quarkus.hibernate-orm."audit-2".datasource=audit-ds
Defensive patterns

Strategy: validation

Validate before calling

Set<String> userPuNames = /* names from persistence.xml + quarkus.hibernate-orm."<name>" keys */;
if (userPuNames.contains(contributedPuName)) {
    throw new IllegalArgumentException("PU name conflict: " + contributedPuName);
}

Prevention

When it happens

Trigger: An AdditionalPersistenceUnitBuildItem produced by an extension has a persistenceUnitName that matches a name present in persistence.xml descriptors or in quarkus.hibernate-orm."<name>".* configuration processed in buildBlockingPersistenceUnitFromPersistenceXml.

Common situations: Naming an extension-contributed PU the same as an application persistence.xml PU (e.g. both 'customers'); enabling an extension that contributes a PU while the app already defined that name in application.properties.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/d6c70b35fdb338dd. Report an issue: GitHub.