Netflix/Hystrix · error · IllegalStateException

Request caching is not available. Maybe you need to initiali

Error message

Request caching is not available. Maybe you need to initialize the HystrixRequestContext?

What it means

HystrixRequestCache.get() looks up the per-request cache map via a HystrixRequestVariable backed by HystrixRequestContext; when a cacheKey exists but requestVariableForCache.get(...) returns null, the HystrixRequestContext was never initialized for this thread, so request caching cannot work and IllegalStateException is thrown with the hint 'Maybe you need to initialize the HystrixRequestContext?'.

Source

Thrown at hystrix-core/src/main/java/com/netflix/hystrix/HystrixRequestCache.java:104

                c = existing;
            }
        }
        return c;
    }

    /**
     * Retrieve a cached Future for this request scope if a matching command has already been executed/queued.
     * 
     * @return {@code Future<T>}
     */
    // suppressing warnings because we are using a raw Future since it's in a heterogeneous ConcurrentHashMap cache
    @SuppressWarnings({ "unchecked" })
    /* package */<T> HystrixCachedObservable<T> get(String cacheKey) {
        ValueCacheKey key = getRequestCacheKey(cacheKey);
        if (key != null) {
            ConcurrentHashMap<ValueCacheKey, HystrixCachedObservable<?>> cacheInstance = requestVariableForCache.get(concurrencyStrategy);
            if (cacheInstance == null) {
                throw new IllegalStateException("Request caching is not available. Maybe you need to initialize the HystrixRequestContext?");
            }
            /* look for the stored value */
            return (HystrixCachedObservable<T>) cacheInstance.get(key);
        }
        return null;
    }

    /**
     * Put the Future in the cache if it does not already exist.
     * <p>
     * If this method returns a non-null value then another thread won the race and it should be returned instead of proceeding with execution of the new Future.
     * 
     * @param cacheKey
     *            key as defined by {@link HystrixCommand#getCacheKey()}
     * @param f
     *            Future to be cached
     * 
     * @return null if nothing else was in the cache (or this {@link HystrixCommand} does not have a cacheKey) or previous value if another thread beat us to adding to the cache

View on GitHub (pinned to 5ce3bc58c3)

Solutions

  1. Wrap the request lifecycle: HystrixRequestContext ctx = HystrixRequestContext.initializeContext(); try { ...commands... } finally { ctx.shutdown(); }
  2. Install a servlet Filter (or framework interceptor) that initializes/shuts down the context per request
  3. For thread hopping, propagate the context explicitly or implement HystrixConcurrencyStrategy.wrapCallable to carry it
  4. If request caching is unwanted, remove the getCacheKey() override so the cache path is skipped

Example fix

// before
HystrixRequestContext ctx = HystrixRequestContext.initializeContext();
// after (missing)
// missing
HystrixRequestContext ctx = HystrixRequestContext.initializeContext();
try {
  String a = new GetOrderCommand(id).execute();
  String b = new GetOrderCommand(id).execute(); // served from cache
} finally {
  ctx.shutdown();
}
Defensive patterns

Strategy: validation

Validate before calling

if (command.getCacheKey() != null && !HystrixRequestContext.isCurrentThreadInitialized()) {
  // initialize or skip request caching
  HystrixRequestContext.initializeContext(); // remember to shutdown later
}

Type guard

null

Try / catch

catch (IllegalStateException e) { if (e.getMessage().contains("initialize the HystrixRequestContext")) { try (HystrixRequestContext ctx = HystrixRequestContext.initializeContext()) { /* retry command */ } } } — note initializeContext returns the context; shutdown in finally.

Prevention

When it happens

Trigger: Executing a command that implements getCacheKey() (or a collapser) on a thread whose HystrixRequestContext was never initialized — e.g. calling queue()/execute()/toObservable() without wrapping in HystrixRequestContext.initializeContext(), or on a non-web thread (scheduler, @Async executor, grpc netty thread) that never ran the init.

Common situations: First use of request caching in a batch job or main() without the context; async/thread-pool hopping losing the thread-local context (HystrixRequestContext is ThreadLocal, not InheritableThreadLocal); servlet filters not installed; unit tests executing commands without shutdown()/context setup.

Related errors


AI-assisted analysis of Netflix/Hystrix@5ce3bc58c3 (2026-08-14). Data as JSON: /api/errors/e19aa3e5e0f7cfe3. Report an issue: GitHub.