{"record":{"id":"0585e251827c035b","repo":"thanos-io/thanos","slug":"no-metadata","errorCode":null,"errorMessage":"no metadata","messagePattern":"no metadata","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/metadata/metadata.go","lineNumber":84,"sourceCode":"\n\tmetric string\n\tlimit  int\n\n\twarnings    annotations.Annotations\n\tmetadataMap map[string][]metadatapb.Meta\n\tmu          sync.Mutex\n}\n\nfunc (srv *metadataServer) Send(res *metadatapb.MetricMetadataResponse) error {\n\tif res.GetWarning() != \"\" {\n\t\tsrv.mu.Lock()\n\t\tdefer srv.mu.Unlock()\n\t\tsrv.warnings.Add(errors.New(res.GetWarning()))\n\t\treturn nil\n\t}\n\n\tif res.GetMetadata() == nil {\n\t\treturn errors.New(\"no metadata\")\n\t}\n\n\t// If limit is set to 0, we don't need to add anything.\n\tif srv.limit == 0 {\n\t\treturn nil\n\t}\n\n\tsrv.mu.Lock()\n\tdefer srv.mu.Unlock()\n\tfor k, v := range res.GetMetadata().Metadata {\n\t\tif metadata, ok := srv.metadataMap[k]; !ok {\n\t\t\t// If limit is set and it is positive, we limit the size of the map.\n\t\t\tif srv.limit < 0 || srv.limit > 0 && len(srv.metadataMap) < srv.limit {\n\t\t\t\tsrv.metadataMap[k] = v.Metas\n\t\t\t}\n\t\t} else {\n\t\t\t// There shouldn't be many metadata for one single metric.\n\t\tOuter:","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/thanos-io/thanos/blob/35b8b991177def87ed52dcf10f9b6d87f07282c8/pkg/metadata/metadata.go#L66-L102","documentation":"metadataServer.Send rejects any response that carries neither a warning nor metadata payload, returning a bare 'no metadata' error. It guards the stream invariant that every non-warning message must include metadata.","triggerScenarios":"The upstream metadata service sends a MetricMetadataResponse whose metadata field is nil and whose warning is empty.","commonSituations":"Malformed or truncated upstream responses; a store node bug emitting empty messages; protobuf deserialization yielding a nil payload.","solutions":["Check the version compatibility between cloud proxy and Vizier metadata service and upgrade to matching versions","Inspect the upstream service logs for a node emitting empty responses","Retry the metadata request; if reproducible, report the upstream bug","Handle the error in the stream consumer so one bad message does not abort valid data already received"],"exampleFix":"// before\nif res.GetMetadata() == nil {\n    return errors.New(\"no metadata\")\n}\n// after\nif res.GetMetadata() == nil && res.GetWarning() == \"\" {\n    return errors.New(\"no metadata in response and no warning present\")\n}","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"func hasPayload(res *metadatapb.MetricMetadataResponse) bool {\n    return res != nil && (res.GetMetadata() != nil || res.GetWarning() != \"\")\n}","tryCatchPattern":"if err := streamSend(res); err != nil {\n    if strings.Contains(err.Error(), \"no metadata\") {\n        // skip malformed message, continue consuming stream\n    }\n}","preventionTips":["Keep proxy and metadata service versions aligned","Guard stream consumers against nil payloads before processing","Report reproducible empty-message bugs upstream"],"tags":["grpc","streaming","protocol"],"backgroundTag":"unexpected-response-shape","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"}