Next Practical Step
Set httpclient4.time_to_live below the smallest idle timeout in the path, enable validate_after_inactivity, then re-run the failing scenario.
Fix JMeter EOFException Premature EOF and Unexpected end of file from server: keep-alive mismatch, load balancer idle timeouts, and gzip truncation.
Samplers fail while reading the response body, in the View Results Tree listener or jmeter.log:
Response code: Non HTTP response code: java.io.EOFExceptionResponse message: Non HTTP response message: Premature EOFOr when the connection dies before any response bytes arrive:
Response code: Non HTTP response code: java.io.IOExceptionResponse message: Non HTTP response message: Unexpected end of file from serverThe failures are usually intermittent and increase with test duration or concurrency.
The server, or a load balancer in front of it, closed the connection while JMeter was still using it: mid-response, or between a pooled connection’s reuse. The fix is to align client connection lifetimes with server-side timeouts, and to rule out servers that abort responses under load.
| Cause | Specific Error | Why it happens |
|---|---|---|
| Server or LB idle timeout shorter than client reuse window | Unexpected end of file from server | The server closes idle keep-alive sockets (AWS ALB defaults to 60s) and JMeter reuses one that is already dead |
| Server aborts mid-response under load | Premature EOF | Worker crashes, OOM kills, or request cancellations cut the response stream |
| Truncated gzip or deflate stream | EOFException while decompressing | The compressed body ends before its terminator; some applications signal stream end early |
| Proxy or CDN cuts long responses | Premature EOF on large downloads | An intermediate hop applies its own response size or time limit |
| Missing Content-Length with Connection: close | Ambiguous body end | HTTP/1.0-style responses rely on connection close, which races with pooled reuse |
Cap how long JMeter reuses a connection, and validate idle connections before use, in user.properties:
# Absolute connection lifetime in milliseconds: retire connections before the server doeshttpclient4.time_to_live=30000# Check idle connections before reuse (milliseconds)httpclient4.validate_after_inactivity=2000Set time_to_live below the smallest idle timeout in the path (load balancer, reverse proxy, application server). Full tuning guidance is in NoHttpResponseException, which shares this root cause.
If the stack includes AWS ALB/CLB, nginx, HAProxy, or a CDN:
time_to_live, or lower time_to_live below the LB timeout.If Premature EOF appears only at high concurrency, the response stream is being cut by the server itself:
dmesg for OOM kills) at the failure timestamps.When a known-buggy application ends gzip or deflate streams early, JMeter can tolerate it:
# Ignore EOFException on early-ended compressed streamshttpclient4.gzip_relax_mode=truehttpclient4.deflate_relax_mode=trueUse these only after verifying the response content is actually complete: relaxed mode hides real truncation as readily as it hides harmless stream-end signaling.
Re-run the soak or high-concurrency scenario and confirm the EOF samples disappear. Compare total sample counts and error rates before and after; a correct fix removes the errors without changing response times in any meaningful way.
| Resource | Use when |
|---|---|
| NoHttpResponseException | The sibling keep-alive race with no response bytes at all |
| Socket closed / connection reset | TCP RST variants of the same connection-lifetime family |
| HTTP 502/503/504 | The proxy reports the failure instead of dropping the connection |
| Properties Cheat Sheet | Interactive lookup for httpclient4.* tuning properties |
The response stream ended before the complete body arrived. JMeter was still reading when the connection closed, so the sample fails instead of returning a full response.
No. The connection was closed on the server side, by the application, a load balancer, or a proxy. JMeter only reports the cut stream; the fix lives in timeout alignment or server capacity.
Only after confirming that a specific application sends complete bodies with early-ended gzip streams. Relaxed mode also masks genuine truncation, so treat it as a targeted workaround, not a default.
Pooled connections accumulate idle time in soak tests. Once a connection sits idle longer than the server’s keep-alive timeout, the next reuse hits a dead socket, which is exactly what time_to_live and validate_after_inactivity prevent.