{"record":{"id":"db892c39ac9ff97e","repo":"SonarSource/sonarqube","slug":"fail-to-parse-protobuf-response-of","errorCode":null,"errorMessage":"Fail to parse protobuf response of ","messagePattern":"Fail to parse protobuf response of ","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"sonar-ws/src/main/java/org/sonarqube/ws/client/BaseService.java","lineNumber":64,"sourceCode":"    return call(request, parser, MediaTypes.PROTOBUF);\n  }\n\n  protected <T extends Message> T call(BaseRequest request, Parser<T> parser, String mediaType) {\n    request.setMediaType(mediaType);\n    WsResponse response = call(request);\n    return convert(response, parser);\n  }\n\n  protected WsResponse call(WsRequest request) {\n    return wsConnector.call(request).failIfNotSuccessful();\n  }\n\n  public static <T extends Message> T convert(WsResponse response, Parser<T> parser) {\n    try (InputStream byteStream = response.contentStream()) {\n      // HTTP header \"Content-Type\" is not verified. It may be different than protobuf.\n      return parser.parseFrom(byteStream);\n    } catch (Exception e) {\n      throw new IllegalStateException(\"Fail to parse protobuf response of \" + response.requestUrl(), e);\n    }\n  }\n\n  protected String path() {\n    return controller;\n  }\n\n  protected String path(String action) {\n    return String.format(\"%s/%s\", controller, action);\n  }\n\n  @CheckForNull\n  protected static String inlineMultipleParamValue(@Nullable Collection<String> values) {\n    return values == null ? null : String.join(\",\", values);\n  }\n}\n","sourceCodeStart":46,"sourceCodeEnd":81,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/sonar-ws/src/main/java/org/sonarqube/ws/client/BaseService.java#L46-L81","documentation":"BaseService.convert() parses a web service response body as protobuf using the supplied parser. If parseFrom fails for any reason (malformed bytes, HTML error page instead of protobuf, truncated stream), it throws IllegalStateException(\"Fail to parse protobuf response of <url>\") wrapping the original exception. The URL is included to identify which endpoint returned the unparseable body.","triggerScenarios":"Calling a generated WS service method (e.g. call()) whose endpoint returned a body that is not valid protobuf for the expected message type — commonly a reverse proxy or auth gateway returning an HTML login/error page, or a server version mismatch changing the message schema.","commonSituations":"SonarQube behind SSO/LDAP proxy that intercepts requests and returns HTML; calling a newer/older SonarQube server than the client library expects; network middleware rewriting responses; hitting a REST endpoint instead of the protobuf api endpoint.","solutions":["Check the wrapped cause and fetch response.requestUrl() manually to see what the server actually returned.","Verify no proxy/SSO gateway is intercepting the request and returning HTML (check auth/cookies).","Align the sonar-ws client version with the SonarQube server version.","Retry the call — transient truncation can also cause parse failures."],"exampleFix":"// before\nWsResponse response = wsConnector.call(request);\nMyMessage msg = convert(response, MyMessage.parser());\n// after\ntry (WsResponse response = wsConnector.call(request)) {\n  if (!\"application/x-protobuf\".contains(response.contentType())) {\n    throw new IllegalStateException(\"Unexpected content type from \" + response.requestUrl());\n  }\n  MyMessage msg = convert(response, MyMessage.parser());\n}","handlingStrategy":"try-catch","validationCode":"if (!\"application/x-protobuf\".equals(response.contentType())) {\n  throw new IllegalStateException(\"Endpoint returned non-protobuf content: \" + response.requestUrl());\n}","typeGuard":null,"tryCatchPattern":"try {\n  MyMessage msg = convert(response, MyMessage.parser());\n} catch (IllegalStateException e) {\n  // cause holds the parse error; log response.requestUrl() and re-check auth/proxy\n  throw new RuntimeException(\"Non-protobuf body from \" + response.requestUrl(), e);\n}","preventionTips":["Pin sonar-ws client version to match the SonarQube server version.","Ensure no SSO/proxy gateway intercepts the request and returns HTML.","Verify the Content-Type header before parsing."],"tags":["protobuf","parsing","http"],"backgroundTag":"protobuf-unmarshal-failed","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}