{"record":{"id":"b1445ddce98869d7","repo":"thanos-io/thanos","slug":"unmarshal-response","errorCode":null,"errorMessage":"unmarshal response","messagePattern":"unmarshal response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/store/prometheus.go","lineNumber":419,"sourceCode":"\t\treturn nil, errors.Wrap(err, \"copy response\")\n\t}\n\n\tsb := p.getBuffer()\n\tvar decomp []byte\n\ttracing.DoInSpan(ctx, \"decompress_response\", func(ctx context.Context) {\n\t\tdecomp, err = snappy.Decode(*sb, buf.Bytes())\n\t})\n\tdefer p.putBuffer(sb)\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"decompress response\")\n\t}\n\n\tvar data prompb.ReadResponse\n\ttracing.DoInSpan(ctx, \"unmarshal_response\", func(ctx context.Context) {\n\t\terr = proto.Unmarshal(decomp, &data)\n\t})\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"unmarshal response\")\n\t}\n\tif len(data.Results) != 1 {\n\t\treturn nil, errors.Errorf(\"unexpected result size %d\", len(data.Results))\n\t}\n\n\tfor _, ts := range data.Results[0].Timeseries {\n\t\tlabelpb.ReAllocZLabelsStrings(&ts.Labels)\n\t}\n\n\treturn &data, nil\n}\n\nfunc (p *PrometheusStore) chunkSamples(series *prompb.TimeSeries, maxSamplesPerChunk int, calculateChecksums bool) (chks []storepb.AggrChunk, err error) {\n\tsamples := series.Samples\n\thasher := hashPool.Get().(hash.Hash64)\n\tdefer hashPool.Put(hasher)\n\n\tfor len(samples) > 0 {","sourceCodeStart":401,"sourceCodeEnd":437,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/store/prometheus.go#L401-L437","documentation":"PrometheusStore's fetchSampledResponse decompresses a snappy-encoded remote-read response and proto.Unmarshals it into prompb.ReadResponse. If the protobuf payload is corrupt, truncated, or not a valid ReadResponse, the wrapped error \"unmarshal response\" is returned. It indicates the upstream Prometheus endpoint returned bytes that could not be parsed as the expected remote-read protobuf.","triggerScenarios":"Calling Series on a PrometheusStore whose remote /api/v1/read endpoint returns malformed, truncated, or non-protobuf data (e.g. an HTML error page that bypassed the status-code check, a proxy mangling the body, or a Prometheus version responding with an unexpected encoding).","commonSituations":"Reverse proxy or service mesh rewriting/compressing the response body; hitting the wrong URL (query API instead of read API); Prometheus remote-read returning chunked/streamed encoding the client doesn't expect; snappy compression mismatch between client and server.","solutions":["Verify the store's base URL points at a Prometheus instance supporting the remote read API (/api/v1/read) and that the response Content-Encoding (snappy) is not stripped by proxies","Check Prometheus version compatibility with the X-Prometheus-Remote-Read-Version header and AcceptedResponseTypes (STREAMED_XOR_CHUNKS support)","Capture the raw response (curl with Accept-Encoding/Content-Encoding headers) and confirm it is snappy-compressed protobuf","Confirm request timeouts / size limits (MaxBytesReader) are not truncating the body before unmarshal"],"exampleFix":"// before: trusting any 2xx body\npresp, err = p.client.Do(preq.WithContext(ctx))\nif err != nil {\n    return nil, errors.Wrap(err, \"send request\")\n}\n// after: also validate response encoding before unmarshal\nif enc := presp.Header.Get(\"Content-Encoding\"); enc != \"snappy\" {\n    return nil, errors.Errorf(\"unexpected response encoding %q\", enc)\n}","handlingStrategy":"try-catch","validationCode":"if !strings.Contains(resp.Header.Get(\"Content-Type\"), \"protobuf\") { return fmt.Errorf(\"unexpected content type %q\", resp.Header.Get(\"Content-Type\")) }","typeGuard":null,"tryCatchPattern":"series, err := store.Series(ctx, req)\nif err != nil && strings.Contains(err.Error(), \"unmarshal response\") {\n    // treat as upstream protocol issue: check prometheus version/encoding, retry with different response types\n}","preventionTips":["Pin Prometheus versions known to support the remote-read encoding you request","Disable any proxy that re-compresses or rewrites response bodies","Monitor this error rate as a signal of endpoint misconfiguration"],"tags":["prometheus","remote-read","protobuf","unmarshal"],"backgroundTag":"protobuf-unmarshal-failed","analyzedSha":"35b8b991177def87ed52dcf10f9b6d87f07282c8","analyzedAt":"2026-09-07T01:49:59.689Z","contentChangedAt":"2026-09-07T01:49:59.689Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}