hibernate/hibernate-orm · error · ServiceException

Unable to create requested service [${serviceBinding.getServ

Error message

Unable to create requested service [${serviceBinding.getServiceRole().getName()}] due to: ${e.getMessage()}

What it means

When a service is first requested, Hibernate calls its ServiceInitiator via initiateService; if that call throws any non-ServiceException, it is wrapped in ServiceException with the message "Unable to create requested service [<role>] due to: <cause message>". The named service role plus the chained cause identify exactly which configuration failed during registry bootstrap.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/service/internal/AbstractServiceRegistryImpl.java:273

		if ( serviceInitiator == null ) {
			// this condition should never ever occur
			throw new UnknownServiceException( serviceBinding.getServiceRole() );
		}

		try {
			final R service = serviceBinding.getLifecycleOwner().initiateService( serviceInitiator );
			// IMPL NOTE: the register call here is important to avoid potential stack overflow issues
			//		      from recursive calls through #configureService
			if ( service != null ) {
				registerService( serviceBinding, service );
			}
			return service;
		}
		catch ( ServiceException e ) {
			throw e;
		}
		catch ( Exception e ) {
			throw new ServiceException( "Unable to create requested service ["
					+ serviceBinding.getServiceRole().getName() + "] due to: " + e.getMessage(), e );
		}
	}

	@Override
	public <R extends Service> void injectDependencies(@Nonnull ServiceBinding<R> serviceBinding) {
		final R service = serviceBinding.getService();
		applyInjections( service );
		if ( service instanceof ServiceRegistryAwareService serviceRegistryAwareService ) {
			serviceRegistryAwareService.injectServices( this );
		}
	}

	private <R extends Service> void applyInjections(@Nonnull R service) {
		try {
			for ( var method : service.getClass().getMethods() ) {
				final var injectService = method.getAnnotation( InjectService.class );
				if ( injectService != null ) {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Read the 'due to:' suffix and the caused-by stack — fix the underlying condition, not this wrapper
  2. Set hibernate.dialect explicitly (or supply JDBC settings so it can be resolved) when bootstrapping without a live connection
  3. Validate datasource/JNDI configuration before building the registry
  4. In custom initiators, validate inputs and throw ServiceException yourself with a precise message

Example fix

# before
# no dialect, no usable JDBC url at bootstrap
hibernate.connection.url=jdbc:h2:mem:test

# after
hibernate.dialect=org.hibernate.dialect.H2Dialect
hibernate.connection.url=jdbc:h2:mem:test
Defensive patterns

Strategy: try-catch

Validate before calling

// fail fast on the most common root causes before building the registry
if (!configSettings.containsKey(AvailableSettings.DIALECT)
        && !configSettings.containsKey(AvailableSettings.URL)
        && !configSettings.containsKey(AvailableSettings.DATASOURCE)) {
    throw new IllegalStateException("cannot resolve dialect: set hibernate.dialect or JDBC settings");
}

Try / catch

try {
    sessionFactory = new MetadataBuilderImpl(registry).build().buildSessionFactory();
}
catch (ServiceException e) {
    Throwable cause = e.getCause(); // the initiator that actually failed
    throw new BootstrapException("Hibernate bootstrap failed: " + e.getMessage(), cause);
}

Prevention

When it happens

Trigger: Dialect resolution failing (no hibernate.dialect and no resolvable JDBC metadata), connection provider initialization errors, JNDI lookup failures for datasources, malformed cfg.xml/properties, or a custom service initiator throwing an unexpected exception.

Common situations: Native bootstrap without a dialect and without an open JDBC connection to resolve it; typo'd hibernate.dialect class name; missing JNDI name in app-server tests; custom initiator NPEs on unexpected configuration values.

Related errors


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