hibernate/hibernate-orm · critical · ConfigurationException

Inconsistent configuration: 'hibernate.query.plan_cache_max_

Error message

Inconsistent configuration: 'hibernate.query.plan_cache_max_size' can't be set to a negative value (to disable the query plan cache set 'hibernate.query.plan_cache_enabled' to 'false')

What it means

The same bootstrap-time validation in QueryEngineImpl rejects a negative hibernate.query.plan_cache_max_size with ConfigurationException. The message tells you the supported way to disable the cache: set hibernate.query.plan_cache_enabled=false rather than abusing a negative size. Startup aborts while the SessionFactory is being created.

Source

Thrown at hibernate-core/src/main/java/org/hibernate/query/internal/QueryEngineImpl.java:200

		final Integer explicitMaxPlanSize = getInteger(
				QUERY_PLAN_CACHE_MAX_SIZE,
				properties
		);

		//Let's avoid some confusion and check settings consistency:
		final int appliedMaxPlanSize =
				explicitMaxPlanSize == null
						? DEFAULT_QUERY_PLAN_MAX_COUNT
						: explicitMaxPlanSize;
		if ( !useCache && explicitMaxPlanSize != null && appliedMaxPlanSize > 0 ) {
			throw new ConfigurationException( "Inconsistent configuration: '" + QUERY_PLAN_CACHE_MAX_SIZE
												+ "' can only be set to a value greater than zero when '"
												+ QUERY_PLAN_CACHE_ENABLED + "' is enabled" );
		}

		if ( appliedMaxPlanSize < 0 ) {
			throw new ConfigurationException( "Inconsistent configuration: '" + QUERY_PLAN_CACHE_MAX_SIZE
												+ "' can't be set to a negative value (to disable the query plan cache set '"
												+ QUERY_PLAN_CACHE_ENABLED + "' to 'false')" );
		}

		return useCache
				? new QueryInterpretationCacheStandardImpl( appliedMaxPlanSize, serviceRegistry )
				: new QueryInterpretationCacheDisabledImpl( serviceRegistry ); // disabled
	}

	@Override
	public void validateNamedQueries() {
		namedObjectRepository.validateNamedQueries( this );
	}

	@Override
	public NamedObjectRepository getNamedObjectRepository() {
		return namedObjectRepository;
	}

View on GitHub (pinned to fad1729dce)

Solutions

  1. Set hibernate.query.plan_cache_max_size to a positive number, or remove the key entirely.
  2. To turn the cache off, use hibernate.query.plan_cache_enabled=false.
  3. Validate numeric config values at deployment time if they come from environment variables.

Example fix

# before
hibernate.query.plan_cache_max_size=-1

# after
hibernate.query.plan_cache_enabled=false
Defensive patterns

Strategy: validation

Validate before calling

static void checkPlanCacheMaxSize(java.util.Map<String, Object> cfg) {
    Object size = cfg.get("hibernate.query.plan_cache_max_size");
    if (size != null && ((Number) size).intValue() < 0)
        throw new IllegalArgumentException(
            "plan_cache_max_size must be >= 0; disable the cache with plan_cache_enabled=false");
}

Try / catch

try {
    emf = Persistence.createEntityManagerFactory("pu");
} catch (Exception e) {
    // look for ConfigurationException about plan_cache_max_size and fix the property
}

Prevention

When it happens

Trigger: Any configuration source containing hibernate.query.plan_cache_max_size=-1 (or any negative value), commonly an attempt to disable the plan cache by size instead of using the enabled flag.

Common situations: Copying an old snippet that used a negative size as a disable switch; environment-variable arithmetic producing a negative number; merged configs where a default of -1 meets an unset enabled flag.

Related errors


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