SonarSource/sonarqube · error · IllegalStateException
Error while writing protobuf message
Error message
Error while writing protobuf message
What it means
WsUtils.writeProtobuf serializes a protobuf Message either as binary protobuf or as JSON (via ProtobufJsonFormat + JsonWriter) into the HTTP response. Any exception thrown during that serialization is wrapped in an IllegalStateException with this message, since response serialization failures indicate an internal bug rather than a client error.
Source
Thrown at server/sonar-webserver-ws/src/main/java/org/sonar/server/ws/WsUtils.java:50
import static org.sonarqube.ws.MediaTypes.JSON;
import static org.sonarqube.ws.MediaTypes.PROTOBUF;
public interface WsUtils {
static void writeProtobuf(Message msg, Request request, Response response) {
OutputStream output = response.stream().output();
try {
if (request.getMediaType().equals(PROTOBUF)) {
response.stream().setMediaType(PROTOBUF);
msg.writeTo(output);
} else {
response.stream().setMediaType(JSON);
try (JsonWriter writer = JsonWriter.of(new OutputStreamWriter(output, UTF_8))) {
ProtobufJsonFormat.write(msg, writer);
}
}
} catch (Exception e) {
throw new IllegalStateException("Error while writing protobuf message", e);
} finally {
IOUtils.closeQuietly(output);
}
}
static String createHtmlExternalLink(String url, String text) {
return String.format("<a href=\"%s\" target=\"_blank\" rel=\"noopener noreferrer\">%s</a>", url, text);
}
}
View on GitHub (pinned to 184c821202)
Solutions
- Inspect the wrapped cause (e.getCause()) to identify whether it is an IO problem or a protobuf serialization problem
- If the cause is a broken pipe/IO error, it is a client disconnect and can be ignored or logged at debug
- If the cause is ProtobufFormat/serialization, fix the message construction in the WS handler (e.g. invalid enum or bytes field)
Example fix
// before
ProtobufFormat.write(msg, output); // raw bytes when client expects JSON
// after
response.stream().setMediaType(JSON);
try (JsonWriter writer = JsonWriter.of(new OutputStreamWriter(output, UTF_8))) {
ProtobufJsonFormat.write(msg, writer);
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!msg.isInitialized()) throw new Error('Protobuf message not initialized before write'); Type guard
const isWritableMessage = (m) => m && typeof m.isInitialized === 'function' && m.isInitialized();
Try / catch
try { writeProtobuf(msg, request, response); } catch (IllegalStateException e) { if (e.getCause() instanceof IOException) { log.debug('Client aborted', e); } else { throw e; } } Prevention
- Always fully populate required protobuf fields before responding
- Handle client disconnects (broken pipe) as recoverable IO errors
- For custom WS plugins, unit-test serialization via WsUtils.TestRequest/Response
When it happens
Trigger: Writing a web service response whose protobuf message fails ProtobufJsonFormat.write() (e.g. invalid UTF-8 or unserializable field state) or when the underlying OutputStream/JsonWriter throws (client disconnected, broken pipe, IO error).
Common situations: Client aborting the connection mid-response causing a broken pipe; a protobuf field holding invalid state (e.g. bytes that violate the JSON format); custom plugin web services emitting malformed protobufs.
Understand the failure class
Background: "cannot parse invalid wire-format data", "cannot unmarshal", "failed unmarshalling": protobuf unmarshal errors explained — this error's family across 10 libraries.
Related errors
- Can not write message ${msg}
- Fail to write into file:
- Fail to traverse file:
- Fail to open file
- Fail to write into file
AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09).
Data as JSON: /api/errors/d10437ffcd5dcf0d.
Report an issue: GitHub.