{"record":{"id":"37ba89ea99bb3ea0","repo":"thanos-io/thanos","slug":"marshal-read-request","errorCode":null,"errorMessage":"marshal read request","messagePattern":"marshal read request","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/store/prometheus.go","lineNumber":464,"sourceCode":"\t\tchks = append(chks, storepb.AggrChunk{\n\t\t\tMinTime: samples[0].Timestamp,\n\t\t\tMaxTime: samples[chunkSize-1].Timestamp,\n\t\t\tRaw:     &storepb.Chunk{Type: enc, Data: cb, Hash: chkHash},\n\t\t})\n\n\t\tsamples = samples[chunkSize:]\n\t}\n\n\treturn chks, nil\n}\n\nfunc (p *PrometheusStore) startPromRemoteRead(ctx context.Context, q *prompb.Query) (presp *http.Response, err error) {\n\treqb, err := proto.Marshal(&prompb.ReadRequest{\n\t\tQueries:               []*prompb.Query{q},\n\t\tAcceptedResponseTypes: p.remoteReadAcceptableResponses,\n\t})\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"marshal read request\")\n\t}\n\n\tu := *p.base\n\tu.Path = path.Join(u.Path, \"api/v1/read\")\n\n\tpreq, err := http.NewRequest(\"POST\", u.String(), bytes.NewReader(snappy.Encode(nil, reqb)))\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"unable to create request\")\n\t}\n\tpreq.Header.Add(\"Content-Encoding\", \"snappy\")\n\tpreq.Header.Set(\"Content-Type\", \"application/x-stream-protobuf\")\n\tpreq.Header.Set(\"X-Prometheus-Remote-Read-Version\", \"0.1.0\")\n\n\tpreq.Header.Set(\"User-Agent\", clientconfig.ThanosUserAgent)\n\tpresp, err = p.client.Do(preq.WithContext(ctx))\n\tif err != nil {\n\t\treturn nil, errors.Wrap(err, \"send request\")\n\t}","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/store/prometheus.go#L446-L482","documentation":"startPromRemoteRead marshals the prompb.ReadRequest (with the query and accepted response types) using proto.Marshal before sending it over HTTP. If marshaling fails, the wrapped error \"marshal read request\" is returned. Failure here is rare since the request proto is built in-process from valid fields.","triggerScenarios":"proto.Marshal failing on a ReadRequest — practically only when the query contains invalid field state (e.g. nil-required semantics or corrupt matcher data) or an unsupported field produced upstream in the Series call chain.","commonSituations":"Corrupt or oversized query objects passed through layered query trees; custom builds with mismatched prompb generated code; extremely large queries hitting marshal resource limits.","solutions":["Inspect the prompb.Query passed to Series — verify matchers, start, end timestamps are sane and not nil","Regenerate/align prompb Go code with the Prometheus/Thanos API version in go.mod","Reduce query size/complexity and retry"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if q == nil || len(q.Matchers) == 0 { return errors.New(\"invalid query: nil or empty matchers\") }","typeGuard":null,"tryCatchPattern":"resp, err := store.Series(ctx, req)\nif err != nil && strings.Contains(err.Error(), \"marshal read request\") {\n    // inspect the query object passed in; regenerate prompb types\n}","preventionTips":["Keep prompb generated code in sync with the vendored Prometheus version","Validate query structs before handing them to the store","Upgrade Thanos/Prometheus together to avoid proto drift"],"tags":["prometheus","remote-read","protobuf","marshal"],"backgroundTag":"json-marshal-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"}