SonarSource/sonarqube · error · IllegalStateException

Can not write message ${msg}

Error message

Can not write message ${msg}

What it means

Protobuf2.writeTo wraps IOException from Message.writeTo into an IllegalStateException, since serialization to an in-memory or well-behaved stream should not fail. It means the protobuf message could not be written to the output stream.

Source

Thrown at server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/util/Protobuf2.java:41

import com.google.protobuf.Message;
import com.google.protobuf.Parser;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.annotation.CheckForNull;

public class Protobuf2 {

  public static final Protobuf2 PROTOBUF2 = new Protobuf2();

  private Protobuf2() {
  }

  public Protobuf2 writeTo(Message msg, OutputStream output) {
    try {
      msg.writeTo(output);
    } catch (IOException e) {
      throw new IllegalStateException("Can not write message " + msg, e);
    }
    return this;
  }

  public Protobuf2 writeDelimitedTo(Message msg, OutputStream output) {
    try {
      msg.writeDelimitedTo(output);
    } catch (IOException e) {
      throw new IllegalStateException("Can not write message " + msg, e);
    }
    return this;
  }

  public <M extends Message> M parseFrom(Parser<M> parser, InputStream input) {
    try {
      return parser.parseFrom(input);
    } catch (InvalidProtocolBufferException e) {
      throw new IllegalStateException("Can not parse message", e);

View on GitHub (pinned to 184c821202)

Solutions

  1. Check the wrapped IOException cause for the stream failure reason
  2. Verify the OutputStream is open and writable at call time
  3. Ensure required proto2 fields are set before writing (missing fields cause IOException)
  4. Check disk space / connection health for file or socket streams

Example fix

// before
protobuf2.writeTo(msg, outputStream);
// after
try (OutputStream out = Files.newOutputStream(path)) {
  protobuf2.writeTo(msg, out);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (output == null) {
  throw new IllegalArgumentException("OutputStream is null");
}
// for proto2: ensure required fields are set
if (!msg.isInitialized()) {
  throw new IllegalArgumentException("Message missing required fields: " + msg);
}

Type guard

boolean writable(OutputStream out) {
  return out != null; // deeper checks require probing the stream
}

Try / catch

try {
  protobuf2.writeTo(msg, output);
} catch (IllegalStateException e) {
  LOGGER.error("Failed to serialize {}", msg.getDescriptorForType().getFullName(), e.getCause());
}

Prevention

When it happens

Trigger: Calling writeTo(msg, output) when the underlying OutputStream throws IOException: stream closed, broken pipe, disk full for file streams, or missing required fields in proto2 syntax.

Common situations: Writing protobuf-serialized reports/components to files or network streams in CE tasks; streams closed upstream; serialization of messages with unset required fields.

Understand the failure class

Background: json.Marshal / "failed to marshal" errors in Go: why "unsupported type" happens and how to fix it — this error's family across 22 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/2e47c8a0878b53c6. Report an issue: GitHub.