apache/incubator-seata · error · RuntimeException

Invalid event format: expected prefix '{}', got: {}

Error message

Invalid event format: expected prefix '{}', got: {}

What it means

Thrown from SeataHttpWatch.next() when a line received on the event stream does not start with the expected Constants.WATCH_EVENT_PREFIX. The watch protocol requires every line to be '{prefix}{json}'; anything else (a bare JSON object, an SSE 'data:' frame, an HTML error page, or a proxy-injected banner) indicates a protocol mismatch or a non-event payload.

Source

Thrown at common/src/main/java/org/apache/seata/common/util/SeataHttpWatch.java:169

            return false;
        }
    }

    @Override
    public Response<T> next() {
        try {
            /*
            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

View on GitHub (pinned to e01f97c6db)

Solutions

  1. Align client and Seata server versions so WATCH_EVENT_PREFIX matches on both sides.
  2. Bypass or reconfigure proxies/gateways that rewrite event-stream bodies.
  3. Confirm the URL points at the watch API, not an HTML console endpoint.
  4. Log the offending line prefix (already included, truncated to 20 chars) to identify what is actually being sent.
Defensive patterns

Strategy: try-catch

Try / catch

catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Invalid event format")) {
        throw new IllegalStateException("Watch protocol mismatch — check client/server versions and proxies", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Server version emitting a different prefix than the client expects; a proxy rewriting the stream (e.g. converting to SSE 'event:/data:' framing); an error page or plain-text message injected instead of an event; garbage bytes from a corrupted connection.

Common situations: Client/server version skew after upgrading one side only; middleware (API gateway, service mesh) transforming text/event-stream bodies; connecting to a console/UI endpoint instead of the watch API.

Related errors


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