signalapp/Signal-Server · error · WebApplicationException

Invalid protobuf entity

Error message

Invalid protobuf entity

What it means

Thrown when the raw request body of the call-quality survey submission endpoint cannot be parsed as a valid serialized survey-response protobuf entity. The client sent bytes that fail protobuf parsing (empty, truncated, or not protobuf at all), so the survey submission is rejected instead of being stored.

Solutions

  1. Serialize the body with SubmitCallQualitySurveyRequest.toByteArray() (or equivalent) before sending
  2. Validate the payload client-side with parseFrom in a try/catch to catch issues before upload
  3. Confirm Content-Type and transport are not altering the raw bytes

Example fix

// before
byte[] body = jsonMapper.writeValueAsBytes(survey);
// after
SubmitCallQualitySurveyRequest req = buildSurveyRequest(...);
byte[] body = req.toByteArray(); // protobuf, validated by round-trip parse
Defensive patterns

Strategy: try-catch

Validate before calling

try { SubmitCallQualitySurveyRequest.parseFrom(bytes); } catch (InvalidProtocolBufferException e) { throw new IllegalArgumentException("survey body is not valid protobuf"); }

Try / catch

try { submitSurvey(bytes); } catch (WebApplicationException e) { if (e.getResponse().getStatus() == 422) { revalidateAndReserializeProtobuf(); } }

Prevention

When it happens

Trigger: POST to the call quality survey endpoint with surveyResponse bytes that are not a valid SubmitCallQualitySurveyRequest encoding — wrong message type, truncated data, or non-protobuf payload.

Common situations: Client sending JSON instead of protobuf; serializing the wrong message type; partial body due to truncation or encoding transform (e.g. base64-wrapped).

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


AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09). Data as JSON: /api/errors/5ac806ce7ffb5095. Report an issue: GitHub.

Appendix: source

Thrown at service/src/main/java/org/whispersystems/textsecuregcm/controllers/CallQualitySurveyController.java:70

      name = "Retry-After",
      description = "If present, an positive integer indicating the number of seconds before a subsequent attempt could succeed"))
  @RateLimitedByIp(RateLimiters.For.SUBMIT_CALL_QUALITY_SURVEY)
  public void submitCallQualitySurvey(@Auth final Optional<AuthenticatedDevice> authenticatedDevice,
      @RequestBody(description = "A serialized survey response protobuf entity")
      @NotNull final byte[] surveyResponse,
      @HeaderParam(HttpHeaders.USER_AGENT) final String userAgentString,
      @Context final ContainerRequestContext requestContext) {

    if (authenticatedDevice.isPresent()) {
      throw new ForbiddenException("must not use authenticated connection for call quality survey submissions");
    }

    final SubmitCallQualitySurveyRequest submitCallQualitySurveyRequest;

    try {
      submitCallQualitySurveyRequest = SubmitCallQualitySurveyRequest.parseFrom(surveyResponse);
    } catch (final InvalidProtocolBufferException e) {
      throw new WebApplicationException("Invalid protobuf entity", 422);
    }

    final String remoteAddress = (String) requestContext.getProperty(RemoteAddressFilter.REMOTE_ADDRESS_ATTRIBUTE_NAME);

    try {
      callQualitySurveyManager.submitCallQualitySurvey(submitCallQualitySurveyRequest, remoteAddress, userAgentString);
    } catch (final CallQualityInvalidArgumentsException e) {
      throw new WebApplicationException(e.getMessage(), 422);
    }
  }
}

View on GitHub (pinned to 100ab61c82)