apache/incubator-seata · error · RuntimeException
IO Exception during next()
Error message
IO Exception during next()
What it means
Thrown from SeataHttpWatch.next() when reading a line from the event stream raises an IOException — the connection failed at the transport level (reset, timeout, broken pipe) rather than ending cleanly. The original IOException is attached as the cause for diagnosis.
Source
Thrown at common/src/main/java/org/apache/seata/common/util/SeataHttpWatch.java:177
Read a single line and parse it as an event.
Format: "{prefix}{json}\n" where prefix is defined in Constants.WATCH_EVENT_PREFIX.
Each line is a complete event, event type is included in the JSON data.
*/
String line = source.readUtf8Line();
if (line == null) {
throw new RuntimeException("Stream closed unexpectedly");
}
if (!line.startsWith(Constants.WATCH_EVENT_PREFIX)) {
throw new RuntimeException("Invalid event format: expected prefix '" + Constants.WATCH_EVENT_PREFIX
+ "', got: " + (line.length() > 20 ? line.substring(0, 20) + "..." : line));
}
String jsonData = line.substring(Constants.WATCH_EVENT_PREFIX.length());
return parseEvent(jsonData);
} catch (IOException e) {
throw new RuntimeException("IO Exception during next()", e);
}
}
/**
* Parse event JSON into Response object.
* Simplified format: only contains group, timestamp, and metadata fields.
*
* @param json the JSON string to parse
* @return the parsed Response object
* @throws IOException if parsing fails
*/
private Response<T> parseEvent(String json) throws IOException {
try {
T eventData = JsonCodecFactory.getCodec().parseObject(json, eventType);
return new Response<>(Response.Type.UPDATE, eventData);
} catch (Exception e) {
LOGGER.error("Failed to parse event JSON: {}", json, e);View on GitHub (pinned to e01f97c6db)
Solutions
- Inspect the cause chain — SocketTimeoutException means readTimeout is too short for a quiet stream; 'connection reset' points to intermediary or peer drops.
- Raise okhttp readTimeout to 0 (no timeout) or a value larger than the longest expected gap between events.
- Enable TCP keepalive / server-side heartbeats so idle connections are not dropped.
- Wrap iteration in a reconnect loop with backoff as streams are inherently failure-prone.
Example fix
// before
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(10, TimeUnit.SECONDS) // kills quiet SSE streams
.build();
// after
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(0, TimeUnit.MILLISECONDS) // stream never times out between events
.retryOnConnectionFailure(true)
.build(); Defensive patterns
Strategy: retry
Validate before calling
OkHttpClient client = new OkHttpClient.Builder()
.readTimeout(0, TimeUnit.MILLISECONDS) // event streams must not time out between events
.retryOnConnectionFailure(true)
.build(); Try / catch
catch (RuntimeException e) {
Throwable cause = e.getCause();
if (cause instanceof java.net.SocketTimeoutException) {
throw new IllegalStateException("readTimeout too short for watch stream", e);
}
scheduleReconnectWithBackoff(); // reset / broken pipe -> reconnect
} Prevention
- Set OkHttp readTimeout to 0 for SSE-style streams.
- Enable TCP keepalive and server heartbeats so idle connections survive.
- Always inspect the cause chain — it distinguishes config problems from network drops.
When it happens
Trigger: watch.next() with the socket dying mid-read: connection reset by peer, socket read timeout on the OkHttp client, TLS session torn down, or network path loss during event streaming.
Common situations: OkHttp client configured with a short readTimeout that fires on quiet streams; NAT/firewall dropping long-lived idle connections; server or intermediary resetting connections; mobile/unstable networks.
Related errors
- Watch request failed: {}
- Stream closed unexpectedly
- MCP PUT Call TC Failed.
- %s ,cost: %d ms
- connect failed, can not connect to services-server.
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/53c0186033b702e5.
Report an issue: GitHub.