{"record":{"id":"4e08bd372f67864a","repo":"apache/druid","slug":"doesn-t-make-sense-to-use-hybrid-cache-with-both-u","errorCode":null,"errorMessage":"Doesn't make sense to use Hybrid cache with both use and populate disabled for L2, use just L1 cache in this case","messagePattern":"Doesn't make sense to use Hybrid cache with both use and populate disabled for L2, use just L1 cache in this case","errorType":"validation","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"server/src/main/java/org/apache/druid/client/cache/HybridCacheProvider.java","lineNumber":41,"sourceCode":"import com.fasterxml.jackson.annotation.JsonCreator;\nimport com.google.common.base.Preconditions;\nimport com.google.inject.name.Named;\n\npublic class HybridCacheProvider extends HybridCacheConfig implements CacheProvider\n{\n  final CacheProvider level1;\n  final CacheProvider level2;\n\n  @JsonCreator\n  public HybridCacheProvider(\n      @JacksonInject @Named(\"l1\") CacheProvider level1,\n      @JacksonInject @Named(\"l2\") CacheProvider level2\n  )\n  {\n    this.level1 = Preconditions.checkNotNull(level1, \"l1 cache not specified for hybrid cache\");\n    this.level2 = Preconditions.checkNotNull(level2, \"l2 cache not specified for hybrid cache\");\n    if (!getUseL2() && !getPopulateL2()) {\n      throw new IllegalStateException(\n          \"Doesn't make sense to use Hybrid cache with both use and populate disabled for L2, \"\n          + \"use just L1 cache in this case\"\n      );\n    }\n  }\n\n  @Override\n  public Cache get()\n  {\n    return new HybridCache(this, level1.get(), level2.get());\n  }\n}\n","sourceCodeStart":23,"sourceCodeEnd":54,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/server/src/main/java/org/apache/druid/client/cache/HybridCacheProvider.java#L23-L54","documentation":"HybridCacheProvider combines an L1 (on-heap) and L2 (off-heap/remote) cache. Its constructor validates that at least one of useL2 or populateL2 is enabled; if both are false, an L2 tier is pointless, so it throws IllegalStateException telling you to use just L1.","triggerScenarios":"Constructing a hybrid cache where level2.use/level2.populate flags are both false (or default to false and unset) while still configuring a hybrid provider.","commonSituations":"Setting druid.cache.type=hybrid but omitting the L2 use/populate flags (which default to false); copy-pasted config where L2 toggles were disabled; upgrade where flag names changed and L2 settings silently dropped.","solutions":["Set level2.use=true (and level2.populate=true if writes are desired) in cache config","Switch druid.cache.type to the L1 type (e.g. caffeine) and drop the hybrid configuration entirely","Verify the L2 provider (e.g. memcached/redis) config keys are present and correctly named","Remove the hybrid wiring if L2 is genuinely not wanted"],"exampleFix":"// before\n{\"type\": \"hybrid\", \"l1\": {...}, \"l2\": {\"use\": false, \"populate\": false}} // ISE\n// after\n{\"type\": \"hybrid\", \"l1\": {...}, \"l2\": {\"use\": true, \"populate\": true}}","handlingStrategy":"validation","validationCode":"if (\"hybrid\".equals(cacheType) && !l2Use && !l2Populate) {\n  throw new IllegalArgumentException(\"hybrid cache requires level2.use or level2.populate\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Enable level2.use when using hybrid cache","Prefer plain L1 cache type when L2 is not needed","Double-check L2 config keys survive upgrades"],"tags":["cache","configuration","hybrid"],"backgroundTag":"conflicting-config-options","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}