quarkusio/quarkus · error · ConfigurationException

An extension attempted to contribute the default persistence

Error message

An extension attempted to contribute the default persistence unit through the SPI. Contributed persistence units must use a non-default name.

What it means

Quarkus extensions can contribute additional persistence units via the AdditionalPersistenceUnitBuildItem SPI, but the default persistence unit (empty name) must be owned by the application's configuration or persistence.xml, not by an extension. During HibernateOrmProcessor.buildBlockingPersistenceUnitFromPersistenceXml a ConfigurationException is thrown if an extension attempts to contribute a PU with the default name.

Source

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

            HibernateOrmConfig hibernateOrmConfig,
            List<PersistenceXmlDescriptorBuildItem> persistenceXmlDescriptors,
            List<JdbcDataSourceBuildItem> jdbcDataSources,
            List<AdditionalPersistenceUnitBuildItem> additionalPersistenceUnits,
            JpaModelPerPersistenceUnitBuildItem jpaModel,
            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);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Set a distinct non-null, non-empty name on the AdditionalPersistenceUnitBuildItem in your extension
  2. If the intent was to configure the default PU, do it via quarkus.hibernate-orm.* application configuration or persistence.xml instead of the SPI

Example fix

// before
new AdditionalPersistenceUnitBuildItem(null, ...)
// after
new AdditionalPersistenceUnitBuildItem("audit", ...)
Defensive patterns

Strategy: validation

Validate before calling

if (puName == null || puName.isBlank()) {
    throw new IllegalArgumentException("AdditionalPersistenceUnitBuildItem requires a non-default name");
}

Prevention

When it happens

Trigger: A custom Quarkus extension produces an AdditionalPersistenceUnitBuildItem whose persistenceUnitName is null or empty (i.e. PersistenceUnitUtil.isDefaultPersistenceUnit returns true) while persistence.xml descriptors are processed.

Common situations: Writing an in-house extension that reuses the Hibernate ORM SPI and forgetting to set a persistence unit name; copying sample code that omits the name parameter.

Related errors


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