hibernate/hibernate-orm · error · HibernateException

Unable to instantiate ScanningProvider `%s`

Error message

Unable to instantiate ScanningProvider `%s`

What it means

During bootstrap Hibernate resolves the configured ScanningProvider (setting 'hibernate.archive.scanning', see PersistenceSettings.SCANNING). The setting may be an instance, a Class, or a class-name String. Here the setting was a Class, so ScanningHelper calls implClass.getDeclaredConstructor().newInstance() reflectively; any failure (missing or inaccessible no-arg constructor, abstract class or interface, constructor that throws, or the created object not being a ScanningProvider causing a ClassCastException) is wrapped in this HibernateException.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/boot/scan/internal/ScanningHelper.java:115

	private static ScanningProvider determineScanningProviderFromSetting(
			@Nonnull ConfigurationService configurationService,
			@Nonnull ClassLoaderService classLoaderService) {
		var providerSetting = configurationService.getSettings().get( PersistenceSettings.SCANNING );
		if ( providerSetting == null ) {
			return null;
		}

		// might be any of the 3 standard forms
		if ( providerSetting instanceof ScanningProvider instance ) {
			return instance;
		}
		else if ( providerSetting instanceof Class<?> implClass ) {
			try {
				return (ScanningProvider) implClass.getDeclaredConstructor().newInstance();
			}
			catch (Exception e) {
				throw new HibernateException(
						String.format( Locale.ROOT,
								"Unable to instantiate ScanningProvider `%s`",
								implClass.getName()
						),
						e
				);
			}
		}
		else {
			var implClassName = providerSetting.toString();
			var implClass = classLoaderService.classForName( implClassName );
			try {
				return (ScanningProvider) implClass.getDeclaredConstructor().newInstance();
			}
			catch (Exception e) {
				throw new HibernateException(
						String.format( Locale.ROOT,
								"Unable to instantiate ScanningProvider `%s`",

View on GitHub (pinned to fad1729dce)

Solutions

  1. Give the implementation a public no-arg constructor (or a declared constructor accessible to the caller) so getDeclaredConstructor().newInstance() succeeds.
  2. Pass an instance instead of a Class: builder.applySetting(PersistenceSettings.SCANNING, new MyScanningProvider(...)) - the 'instanceof ScanningProvider' branch returns it directly with no reflection.
  3. Inspect the wrapped cause (e) in the stack trace - InstantiationException means abstract/interface, NoSuchMethodException means no no-arg constructor, ClassCastException means wrong interface, InvocationTargetException means your constructor threw.
  4. Verify the class actually implements org.hibernate.boot.scan.spi.ScanningProvider from the same Hibernate version, and that its module exports the package when running on the module path.

Example fix

// before
builder.applySetting( PersistenceSettings.SCANNING, MyScanningProvider.class );
// MyScanningProvider(String cfg) only -> no no-arg constructor -> error

// after
public MyScanningProvider() {
    this(defaultConfig());
}
// or skip reflection entirely:
builder.applySetting( PersistenceSettings.SCANNING, new MyScanningProvider(cfg) );
Defensive patterns

Strategy: validation

Validate before calling

Class<?> impl = MyScanningProvider.class;
if ( !org.hibernate.boot.scan.spi.ScanningProvider.class.isAssignableFrom( impl ) ) {
    throw new IllegalStateException( impl + " is not a ScanningProvider" );
}
try { impl.getDeclaredConstructor(); } // NoSuchMethodException here = would fail in Hibernate
catch ( NoSuchMethodException e ) { throw new IllegalStateException( impl + " needs a no-arg constructor" ); }

Type guard

static boolean instantiableScanningProvider(Object setting) {
    if ( setting instanceof org.hibernate.boot.scan.spi.ScanningProvider ) return true; // instance form: safe
    Class<?> c = setting instanceof Class<?> k ? k : null;
    return c != null
            && org.hibernate.boot.scan.spi.ScanningProvider.class.isAssignableFrom( c )
            && java.lang.reflect.Modifier.isPublic( c.getModifiers() );
}

Try / catch

try {
    Metadata metadata = new MetadataSources( ssr ).buildMetadata();
}
catch ( HibernateException e ) {
    if ( e.getMessage() != null && e.getMessage().startsWith( "Unable to instantiate ScanningProvider" ) ) {
        // e.getCause(): NoSuchMethodException / InstantiationException / InvocationTargetException / ClassCastException
        throw new BootstrapException( "Bad hibernate.archive.scanning setting", e.getCause() );
    }
    throw e;
}

Prevention

When it happens

Trigger: Setting PersistenceSettings.SCANNING ('hibernate.archive.scanning') to a Class object whose declared no-arg constructor cannot be invoked: constructor is private/protected, the class is abstract or an interface, the constructor throws (e.g. looks up env/config), or the class does not implement ScanningProvider so the (ScanningProvider) cast fails inside the try block.

Common situations: Custom scanning provider that only has constructor-arg constructors; a provider whose no-arg constructor does environment lookups that fail in CI; passing a class that implements the SPI from a different Hibernate version where the interface moved; access-control failure under JPMS because the package is not exported/opened.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/837d94cbd40e713b. Report an issue: GitHub.