Netflix/Hystrix · error · IllegalStateException

HystrixRequestContext.initializeContext() must be called at

Error message

HystrixRequestContext.initializeContext() must be called at the beginning of each request before RequestVariable functionality can be used.

What it means

Hystrix request-scoped state (request cache, request log, HystrixRequestVariable) lives in a HystrixRequestContext attached to the current thread. Reading any HystrixRequestVariable throws this IllegalStateException when HystrixRequestContext.getContextForCurrentThread() returns null, i.e. no context was initialized on this thread before the variable was used.

Source

Thrown at hystrix-core/src/main/java/com/netflix/hystrix/strategy/concurrency/HystrixRequestVariableDefault.java:76

    static final Logger logger = LoggerFactory.getLogger(HystrixRequestVariableDefault.class);

    /**
     * Creates a new HystrixRequestVariable that will exist across all threads
     * within a {@link HystrixRequestContext}
     */
    public HystrixRequestVariableDefault() {
    }

    /**
     * Get the current value for this variable for the current request context.
     * 
     * @return the value of the variable for the current request,
     *         or null if no value has been set and there is no initial value
     */
    @SuppressWarnings("unchecked")
    public T get() {
        if (HystrixRequestContext.getContextForCurrentThread() == null) {
            throw new IllegalStateException(HystrixRequestContext.class.getSimpleName() + ".initializeContext() must be called at the beginning of each request before RequestVariable functionality can be used.");
        }
        ConcurrentHashMap<HystrixRequestVariableDefault<?>, LazyInitializer<?>> variableMap = HystrixRequestContext.getContextForCurrentThread().state;

        // short-circuit the synchronized path below if we already have the value in the ConcurrentHashMap
        LazyInitializer<?> v = variableMap.get(this);
        if (v != null) {
            return (T) v.get();
        }

        /*
         * Optimistically create a LazyInitializer to put into the ConcurrentHashMap.
         * 
         * The LazyInitializer will not invoke initialValue() unless the get() method is invoked
         * so we can optimistically instantiate LazyInitializer and then discard for garbage collection
         * if the putIfAbsent fails.
         * 
         * Whichever instance of LazyInitializer succeeds will then have get() invoked which will call
         * the initialValue() method once-and-only-once.

View on GitHub (pinned to 5ce3bc58c3)

Solutions

  1. Initialize the context at the start of each request and shut it down at the end: HystrixRequestContext.initializeContext() ... context.shutdown() in a finally block, typically in a servlet Filter.
  2. For background threads, wrap the work with HystrixContextRunnable/HystrixContextCallable so the context is propagated.
  3. In tests, wrap test bodies with initializeContext/shutdown in setUp/tearDown.
  4. If you do not need request caching or logging, disable them (hystrix.command.<key>.requestCache.enabled=false, requestLog.enabled=false) to avoid touching the request context.

Example fix

// before
String v = new MyCommand(cmdKey).execute(); // getCacheKey set, no context initialized -> IllegalStateException

// after
HystrixRequestContext ctx = HystrixRequestContext.initializeContext();
try {
    String v = new MyCommand(cmdKey).execute();
} finally {
    ctx.shutdown();
}
Defensive patterns

Strategy: validation

Validate before calling

if (HystrixRequestContext.getContextForCurrentThread() == null) {
    HystrixRequestContext.initializeContext(); // or reject/warn before using request-scoped features
}

Try / catch

HystrixRequestContext context = HystrixRequestContext.getContextForCurrentThread();
if (context == null) {
    context = HystrixRequestContext.initializeContext();
    try {
        // request-scoped work
    } finally {
        context.shutdown();
    }
}

Prevention

When it happens

Trigger: Calling get() on a HystrixRequestVariableDefault (directly or via request cache/request log features: getCacheKey(), HystrixRequestLog.getCurrentInstance()) on a thread that never called HystrixRequestContext.initializeContext(); using commands with request caching enabled inside thread pools or async executors that were not context-wrapped.

Common situations: Servlet filter that calls initializeContext()/shutdown() missing or mapped to the wrong URL pattern; invoking Hystrix commands from @Async methods, CompletableFuture, or custom executors where the context ThreadLocal was never set; integration tests that forget to initialize the context.

Related errors


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