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 instance

View on GitHub (pinned to e01f97c6db)

Solutions

  1. Check Seata server health and logs: the non-2xx status is the root cause; the IOException here only masks the body.
  2. Verify the watch URL, port and any auth headers on the OkHttp Call before calling createWatch.
  3. If a proxy sits between client and server, raise its proxy_read_timeout / disable buffering for text/event-stream endpoints.
  4. 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

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


AI-assisted analysis of apache/incubator-seata@e01f97c6db (2026-08-14). Data as JSON: /api/errors/7099c5e37678c866. Report an issue: GitHub.