{"record":{"id":"0c3f3ff68b3150aa","repo":"thanos-io/thanos","slug":"decompress-response","errorCode":null,"errorMessage":"decompress response","messagePattern":"decompress response","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/store/prometheus.go","lineNumber":411,"sourceCode":"\nfunc (p *PrometheusStore) fetchSampledResponse(ctx context.Context, resp *http.Response) (_ *prompb.ReadResponse, err error) {\n\tdefer runutil.ExhaustCloseWithLogOnErr(p.logger, resp.Body, \"prom series request body\")\n\n\tb := p.getBuffer()\n\tbuf := bytes.NewBuffer(*b)\n\tdefer p.putBuffer(b)\n\tif _, err := io.Copy(buf, resp.Body); err != nil {\n\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","sourceCodeStart":393,"sourceCodeEnd":429,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/store/prometheus.go#L393-L429","documentation":"After copying the response, fetchSampledResponse snappy-decodes the raw bytes into a pooled buffer; a decode failure is wrapped as 'decompress response'. The payload received was not valid snappy-compressed remote-read data.","triggerScenarios":"The bytes returned by the remote-read endpoint are not valid snappy data — e.g. an error page (HTML/JSON) sent with a protobuf content type, a truncated body, or a corrupted response.","commonSituations":"Auth/proxy layers returning error bodies while status looks OK; truncated responses cut by proxies; pointing at an endpoint that does not snappy-encode remote read responses as expected.","solutions":["Log/inspect the raw response body to see if it's an error page instead of snappy protobuf data.","Fix auth/proxy layers that return non-snappy error bodies for remote-read requests.","Check for truncation (compare Content-Length with bytes read) and raise proxy timeouts.","Verify the target endpoint actually supports snappy-compressed sampled remote read."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"body, _ := io.ReadAll(resp.Body)\nif len(body) > 0 && body[0] == '<' || bytes.HasPrefix(body, []byte{\"{\"})) {\n    return fmt.Errorf(\"remote read returned non-snappy payload: %s\", truncate(body, 200))\n}","typeGuard":null,"tryCatchPattern":"data, err := s.fetchSampledResponse(ctx, resp, ...)\nif err != nil {\n    if strings.Contains(err.Error(), \"decompress response\") {\n        // payload not snappy: inspect raw body for error pages; fix auth/proxy layer\n    }\n    return err\n}","preventionTips":["Ensure auth middlewares return proper HTTP error status rather than 200 with an error body.","Check for truncating proxies on the remote-read path.","Confirm the endpoint snappy-encodes sampled remote read responses.","Capture and log response bodies on decompression failure for diagnosis."],"tags":["prometheus","remote-read","snappy","decompression"],"backgroundTag":"decompression-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"}