apache/incubator-seata · error · FrameworkException
Watch request failed: {}
Error message
Watch request failed: {} What it means
Thrown by SeataHttpWatch.createWatch when the OkHttp call executing a watch (long-poll/SSE) request fails while reading the error response body. The server returned a non-success HTTP status, and additionally the attempt to drain the body to include it in the diagnostic message raised an IOException, so the original failure is wrapped in a FrameworkException with the status-line message only.
Source
Thrown at common/src/main/java/org/apache/seata/common/util/SeataHttpWatch.java:105
*
* @param call the prepared HTTP call
* @param eventType the class type for deserializing event data
* @param <T> the event data type
* @return a Watch instance
* @throws IOException if the request fails
*/
public static <T> SeataHttpWatch<T> createWatch(Call call, Class<T> eventType) throws IOException {
okhttp3.Response response = call.execute();
if (!response.isSuccessful()) {
String respBody = null;
try (ResponseBody body = response.body()) {
if (body != null) {
respBody = body.string();
}
} catch (IOException e) {
throw new FrameworkException(e, "Watch request failed: " + response.message());
}
throw new FrameworkException(
String.format("Watch request failed with code %d: %s", response.code(), respBody));
}
// Verify Content-Type is event stream
String contentType = response.header("Content-Type");
if (contentType == null || !contentType.contains("text/event-stream")) {
LOGGER.warn("Expected Content-Type: text/event-stream, got: {}", contentType);
}
return new SeataHttpWatch<>(response.body(), call, eventType);
}
/**
* Create a Watch instance with a prepared request
*
* @param client the OkHttpClient instanceView on GitHub (pinned to e01f97c6db)
Solutions
- Check Seata server health and logs: the non-2xx status is the root cause; the IOException here only masks the body.
- Verify the watch URL, port and any auth headers on the OkHttp Call before calling createWatch.
- If a proxy sits between client and server, raise its proxy_read_timeout / disable buffering for text/event-stream endpoints.
- Retry the watch creation with backoff — a transient 5xx plus reset should succeed on a later attempt.
Example fix
// before
SeataHttpWatch<MyEvent> watch = SeataHttpWatch.createWatch(call, MyEvent.class);
// after: validate the endpoint is healthy first, and wrap transient failures
okhttp3.Response probe = probeCall.execute();
if (!probe.isSuccessful()) {
throw new IllegalStateException("watch endpoint unhealthy: " + probe.code());
}
probe.close();
SeataHttpWatch<MyEvent> watch;
try {
watch = SeataHttpWatch.createWatch(call, MyEvent.class);
} catch (FrameworkException e) {
// log code + message, schedule reconnect with backoff
throw e;
} Defensive patterns
Strategy: retry
Validate before calling
okhttp3.Request probe = call.request().newBuilder().head().build();
try (okhttp3.Response r = client.newCall(probe).execute()) {
if (!r.isSuccessful()) {
throw new IllegalStateException("watch endpoint returned " + r.code());
}
} Try / catch
catch (FrameworkException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Watch request failed")) {
scheduleReconnectWithBackoff();
} else {
throw e;
}
} Prevention
- Health-check the watch endpoint before establishing a long-lived watch.
- Build OkHttp clients with retryOnConnectionFailure(true).
- Keep server and client on compatible releases so error paths stay well-formed.
When it happens
Trigger: Calling createWatch(call, eventType) where call.execute() returns a non-2xx response (e.g. 401/403/404/500 from the server) and reading response.body().string() itself fails — typically because the connection was reset mid-body or the body stream was already closed/expired.
Common situations: Seata server (http://host:port) is up enough to answer with an error but drops the connection while streaming the error body; auth token rejected with a truncated body; proxies/load balancers (nginx, istio) closing errored responses early; server restarting during the watch handshake.
Related errors
- Watch request failed with code %d: %s
- IO Exception during next()
- URL must not be null or blank
- Stream closed unexpectedly
- Invalid port number in: {}
AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14).
Data as JSON: /api/errors/7099c5e37678c866.
Report an issue: GitHub.