Netflix/Hystrix · error · IllegalStateException
Response has already terminated so response can not be set :
Error message
Response has already terminated so response can not be set : {response} What it means
CollapsedRequestSubject.setResponse() pushes a batch result to a single collapsed request; it is legal only while the underlying subject is not terminated (hasCompleted()/hasThrowable() both false). Calling it after the subject already completed or errored throws IllegalStateException('Response has already terminated so response can not be set'). This almost always indicates a bug in the collapser's mapResponseToRequests.
Source
Thrown at hystrix-core/src/main/java/com/netflix/hystrix/collapser/CollapsedRequestSubject.java:107
public R getArgument() {
return argument;
}
/**
* When set any client thread blocking on get() will immediately be unblocked and receive the single-valued response.
*
* @throws IllegalStateException
* if called more than once or after setException.
* @param response response to give to initial command
*/
@Override
public void setResponse(T response) {
if (!isTerminated()) {
subject.onNext(response);
valueSet.set(true);
subject.onCompleted();
} else {
throw new IllegalStateException("Response has already terminated so response can not be set : " + response);
}
}
/**
* Emit a response that should be OnNexted to an Observer
* @param response response to emit to initial command
*/
@Override
public void emitResponse(T response) {
if (!isTerminated()) {
subject.onNext(response);
valueSet.set(true);
} else {
throw new IllegalStateException("Response has already terminated so response can not be set : " + response);
}
}
@OverrideView on GitHub (pinned to 5ce3bc58c3)
Solutions
- Audit mapResponseToRequests: each request must receive exactly ONE of setResponse/emitResponse-final/setException/setComplete
- Guard each call: if (request.isTerminated()) skip / or use setException-if-not-set semantics where appropriate
- Ensure error paths return from the mapping method instead of falling through to response-setting code
- Add unit tests with partially-failing batches (one request errors, others succeed)
Example fix
// before
for (CollapsedRequest<String, Integer> r : requests) {
try { r.setResponse(map.get(r.getArgument())); }
catch (Exception e) { r.setException(e); }
if (someFlag) r.setResponse(fallbackValue); // second terminal -> ISE
}
// after
for (CollapsedRequest<String, Integer> r : requests) {
try { r.setResponse(map.get(r.getArgument())); }
catch (Exception e) { r.setException(e); }
} Defensive patterns
Strategy: validation
Validate before calling
// before mapping, check termination state via a tracked set of served requests
Set<CollapsedRequest<R, A>> served = new HashSet<>();
// in loop: if (!served.contains(request)) { request.setResponse(v); served.add(request); } Type guard
null
Try / catch
catch (IllegalStateException e) { if (e.getMessage().contains("already terminated")) { // mapping bug: log request argument and skip — do not kill the whole batch } } Prevention
- Enforce one terminal event per CollapsedRequest in mapResponseToRequests
- Return early from error branches instead of falling through
- Test with mixed success/failure batches
When it happens
Trigger: A mapResponseToRequests implementation that calls setResponse()/setException() twice for one request, or calls setResponse after setComplete/exception already terminated that request (e.g. error path then success path both execute in a loop).
Common situations: Hand-written batch mapping logic with early-return error handling that later continues the loop and sets responses again; shard-parallel batch responses racing to complete the same CollapsedRequest; refactoring a collapser and losing the 'one terminal event per request' invariant.
Related errors
- Response has already terminated so exception can not be set
- HystrixCollapser failed while executing.
- Not an event that can be converted to HystrixEventType.Colla
- Trying to start null batch which means it was shutdown alrea
- Collapser method must have one argument: {}
AI-assisted analysis of Netflix/Hystrix@5ce3bc58c3 (2026-08-14).
Data as JSON: /api/errors/bf0dfa7a0bf1d703.
Report an issue: GitHub.