{"record":{"id":"87abb552d88fd064","repo":"hibernate/hibernate-orm","slug":"inconsistent-configuration-hibernate-query-plan","errorCode":null,"errorMessage":"Inconsistent configuration: 'hibernate.query.plan_cache_max_size' can only be set to a value greater than zero when 'hibernate.query.plan_cache_enabled' is enabled","messagePattern":"Inconsistent configuration: 'hibernate\\.query\\.plan_cache_max_size' can only be set to a value greater than zero when 'hibernate\\.query\\.plan_cache_enabled' is enabled","errorType":"exception","errorClass":"ConfigurationException","httpStatus":null,"severity":"critical","filePath":"hibernate-core/src/main/java/org/hibernate/query/internal/QueryEngineImpl.java","lineNumber":194,"sourceCode":"\t\tfinal boolean useCache = getBoolean(\n\t\t\t\tQUERY_PLAN_CACHE_ENABLED,\n\t\t\t\tproperties,\n\t\t\t\t// enabled by default\n\t\t\t\ttrue\n\t\t);\n\n\t\tfinal Integer explicitMaxPlanSize = getInteger(\n\t\t\t\tQUERY_PLAN_CACHE_MAX_SIZE,\n\t\t\t\tproperties\n\t\t);\n\n\t\t//Let's avoid some confusion and check settings consistency:\n\t\tfinal int appliedMaxPlanSize =\n\t\t\t\texplicitMaxPlanSize == null\n\t\t\t\t\t\t? DEFAULT_QUERY_PLAN_MAX_COUNT\n\t\t\t\t\t\t: explicitMaxPlanSize;\n\t\tif ( !useCache && explicitMaxPlanSize != null && appliedMaxPlanSize > 0 ) {\n\t\t\tthrow new ConfigurationException( \"Inconsistent configuration: '\" + QUERY_PLAN_CACHE_MAX_SIZE\n\t\t\t\t\t\t\t\t\t\t\t\t+ \"' can only be set to a value greater than zero when '\"\n\t\t\t\t\t\t\t\t\t\t\t\t+ QUERY_PLAN_CACHE_ENABLED + \"' is enabled\" );\n\t\t}\n\n\t\tif ( appliedMaxPlanSize < 0 ) {\n\t\t\tthrow new ConfigurationException( \"Inconsistent configuration: '\" + QUERY_PLAN_CACHE_MAX_SIZE\n\t\t\t\t\t\t\t\t\t\t\t\t+ \"' can't be set to a negative value (to disable the query plan cache set '\"\n\t\t\t\t\t\t\t\t\t\t\t\t+ QUERY_PLAN_CACHE_ENABLED + \"' to 'false')\" );\n\t\t}\n\n\t\treturn useCache\n\t\t\t\t? new QueryInterpretationCacheStandardImpl( appliedMaxPlanSize, serviceRegistry )\n\t\t\t\t: new QueryInterpretationCacheDisabledImpl( serviceRegistry ); // disabled\n\t}\n\n\t@Override\n\tpublic void validateNamedQueries() {\n\t\tnamedObjectRepository.validateNamedQueries( this );","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/query/internal/QueryEngineImpl.java#L176-L212","documentation":"At SessionFactory bootstrap, QueryEngineImpl cross-checks query plan cache settings. If hibernate.query.plan_cache_max_size is explicitly set to a positive value while hibernate.query.plan_cache_enabled is false, Hibernate treats it as a contradictory configuration and fails startup with ConfigurationException. The check exists so a disabled cache with a tuned size does not silently mislead the operator.","triggerScenarios":"persistence.xml, hibernate.properties, or Spring Boot application.properties containing both hibernate.query.plan_cache_enabled=false and hibernate.query.plan_cache_max_size=2048 (any value > 0). The exception is thrown while the SessionFactory is built, so the application never finishes starting.","commonSituations":"Disabling the plan cache during debugging but leaving an old tuned max-size setting behind; copied tuning profiles from another project; YAML property merging where a profile re-enables or disables one of the two keys.","solutions":["Remove hibernate.query.plan_cache_max_size when the cache is disabled.","Or re-enable the cache: set hibernate.query.plan_cache_enabled=true and keep the max size.","Keep all plan-cache settings in one configuration location so they cannot diverge."],"exampleFix":"# before (application.properties)\nhibernate.query.plan_cache_enabled=false\nhibernate.query.plan_cache_max_size=2048\n\n# after\nhibernate.query.plan_cache_enabled=false\n# plan_cache_max_size removed","handlingStrategy":"validation","validationCode":"static void checkPlanCacheSettings(java.util.Map<String, Object> cfg) {\n    Boolean enabled = (Boolean) cfg.get(\"hibernate.query.plan_cache_enabled\");\n    Object size = cfg.get(\"hibernate.query.plan_cache_max_size\");\n    if (size != null && ((Number) size).intValue() > 0 && Boolean.FALSE.equals(enabled))\n        throw new IllegalArgumentException(\n            \"plan_cache_max_size > 0 requires plan_cache_enabled=true\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    sessionFactory = new Configuration().addProperties(props).buildSessionFactory();\n} catch (org.hibernate.boot.MappingException | RuntimeException e) {\n    // unwrap ConfigurationException and fail fast with the offending keys\n}","preventionTips":["Keep hibernate.query.plan_cache_* settings in one configuration location.","Audit copied tuning profiles before applying them.","Fail fast in CI by booting the SessionFactory in a smoke test."],"tags":["hibernate","configuration","query-plan-cache","startup-failure","boot"],"backgroundTag":"conflicting-configuration-settings","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}