{"record":{"id":"b978c097029bdf12","repo":"thanos-io/thanos","slug":"marshal-symbols","errorCode":null,"errorMessage":"marshal symbols","messagePattern":"marshal symbols","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/receive/writecapnp/marshal.go","lineNumber":136,"sourceCode":"\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\tsymbols, err := wr.NewSymbols()\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"new symbols\")\n\t}\n\tif err := marshalSymbols(builder, symbols); err != nil {\n\t\treturn errors.Wrap(err, \"marshal symbols\")\n\t}\n\treturn nil\n}\n\nfunc marshalSymbols(builder *symboltable.Builder, symbols Symbols) error {\n\toffsets, err := symbols.NewOffsets(builder.Len())\n\tif err != nil {\n\t\treturn err\n\t}\n\tdata := make([]byte, builder.SymbolsSize)\n\tfor k, entry := range builder.Table {\n\t\tend := entry.Start + uint32(len(k))\n\t\tcopy(data[entry.Start:end], k)\n\t\toffsets.Set(int(entry.Index), end)\n\t}\n\n\treturn symbols.SetData(data)\n}","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/receive/writecapnp/marshal.go#L118-L154","documentation":"Wrap of the error from marshalSymbols, which writes the accumulated string symbol table (offsets list plus packed data) into the capnp WriteRequest. Failure means symbols.NewOffsets(len) or symbols.SetData failed; the raw capnp cause is wrapped and indicates an allocation problem on the message.","triggerScenarios":"BuildIntoSingleTenantWriteRequest calling marshalSymbols after collecting all label/exemplar strings, when the capnp message cannot allocate the offsets list or data bytes (arena exhausted, invalid message).","commonSituations":"Very high label cardinality (many unique label names/values) in one write request exhausting the segment; reusing a finalized capnp message.","solutions":["Inspect the wrapped capnp cause for which allocation (NewOffsets vs SetData) failed.","Reduce label cardinality or split the write into multiple requests.","Build the WriteRequest on a fresh capnp message/arena for each call.","Retry; if reproducible with normal payloads, check capnp library version."],"exampleFix":"// before\nerr := BuildIntoSingleTenantWriteRequest(wr, tenant, highCardinalitySeries)\n// after: split by cardinality budget\nfor _, part := range splitSeriesByUniqueStrings(highCardinalitySeries, 10000) {\n    err = BuildIntoSingleTenantWriteRequest(wr, tenant, part)\n}","handlingStrategy":"validation","validationCode":"unique := map[string]struct{}{}\nfor _, ts := range series {\n    for _, l := range ts.Labels { unique[l.Name+\"\\x00\"+l.Value] = struct{}{} }\n}\nif len(unique) > maxSymbolsPerRequest { return errors.New(\"label cardinality too high for one request\") }","typeGuard":null,"tryCatchPattern":"if err := BuildIntoSingleTenantWriteRequest(wr, tenant, series); err != nil {\n    if strings.Contains(err.Error(), \"marshal symbols\") {\n        // split series into smaller requests and retry\n    }\n}","preventionTips":["Bound unique label strings per request","Share a symbol table across series instead of duplicating strings","Watch for cardinality explosions in senders"],"tags":["capnp","serialization","symbol-table","go"],"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"}