{"record":{"id":"0daaaa23c5f707e0","repo":"thanos-io/thanos","slug":"marshal-labels","errorCode":null,"errorMessage":"marshal labels","messagePattern":"marshal labels","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/receive/writecapnp/marshal.go","lineNumber":84,"sourceCode":"\nfunc BuildInto(wr *TimeSeriesTenantTuple, tenant string, tsreq []prompb.TimeSeries, builder *symboltable.Builder) error {\n\tif err := wr.SetTenant(tenant); err != nil {\n\t\treturn errors.Wrap(err, \"set tenant\")\n\t}\n\n\tseries, err := wr.NewTimeSeries(int32(len(tsreq)))\n\tif err != nil {\n\t\treturn err\n\t}\n\tfor i, ts := range tsreq {\n\t\ttsc := series.At(i)\n\n\t\tlblsc, err := tsc.NewLabels(int32(len(ts.Labels)))\n\t\tif err != nil {\n\t\t\treturn errors.Wrap(err, \"new labels\")\n\t\t}\n\t\tif err := marshalLabels(lblsc, ts.Labels, builder); err != nil {\n\t\t\treturn errors.Wrap(err, \"marshal labels\")\n\t\t}\n\t\tif err := marshalSamples(tsc, ts.Samples); err != nil {\n\t\t\treturn errors.Wrap(err, \"marshal samples\")\n\t\t}\n\t\tif err := marshalHistograms(tsc, ts.Histograms); err != nil {\n\t\t\treturn errors.Wrap(err, \"marshal histograms\")\n\t\t}\n\t\tif err := marshalExemplars(tsc, ts.Exemplars, builder); err != nil {\n\t\t\treturn errors.Wrap(err, \"marshal exemplars\")\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc BuildIntoSingleTenantWriteRequest(wr WriteRequest, tenant string, tsreq []prompb.TimeSeries) error {\n\tif err := wr.SetTenant(tenant); err != nil {\n\t\treturn errors.Wrap(err, \"set tenant\")","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/receive/writecapnp/marshal.go#L66-L102","documentation":"After allocating the label list, BuildInto calls marshalLabels to copy each promqltype label (name/value) into the capnp list. Any failure inside that copy (string allocation failure, invalid label data) is wrapped as 'marshal labels'.","triggerScenarios":"marshalLabels fails while setting capnp text fields for a label — usually arena exhaustion from many/long label names or values, or a nil/invalid label entry in ts.Labels.","commonSituations":"Extremely long label names/values from instrumentation; batches near capnp size limits; corrupted or empty label sets produced upstream.","solutions":["Reduce batch size to shrink per-message allocation pressure","Sanitize label names/values (non-empty, sane length) before marshaling","Apply metric relabeling to trim label cardinality","Check capnp library version for string-set size constraints"],"exampleFix":"// before\nfor _, l := range ts.Labels { /* pass through raw */ }\n// after\nfor _, l := range ts.Labels {\n    if l.Name == \"\" || len(l.Value) > 4096 { continue }\n    // marshal\n}","handlingStrategy":"validation","validationCode":"func labelsValid(ts prompb.TimeSeries) bool {\n    for _, l := range ts.Labels {\n        if l.Name == \"\" || len(l.Name) > 512 || len(l.Value) > 8192 { return false }\n    }\n    return true\n}","typeGuard":null,"tryCatchPattern":"if err := BuildInto(tuple, tenant, tsreq, builder); err != nil && strings.Contains(err.Error(), \"marshal labels\") {\n    // sanitize or drop the offending series and continue\n    return rebuildWithoutBadSeries(tsreq)\n}","preventionTips":["Sanitize label names/values before sending","Trim oversized labels with relabel configs","Keep batches small enough to avoid arena exhaustion"],"tags":["capnp","serialization","labels"],"backgroundTag":"schema-validation-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"}