{"record":{"id":"bbe6d0516b11642e","repo":"golang/go","slug":"preprocessed-profile-malformed-header-got-q-want","errorCode":null,"errorMessage":"preprocessed profile malformed header; got %q want %q","messagePattern":"preprocessed profile malformed header; got %q want %q","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/internal/pgo/deserialize.go","lineNumber":45,"sourceCode":"\n\treturn string(hdr) == serializationHeader, nil\n}\n\n// FromSerialized parses a profile from serialization output of Profile.WriteTo.\nfunc FromSerialized(r io.Reader) (*Profile, error) {\n\td := emptyProfile()\n\n\tscanner := bufio.NewScanner(r)\n\tscanner.Split(bufio.ScanLines)\n\n\tif !scanner.Scan() {\n\t\tif err := scanner.Err(); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error reading preprocessed profile: %w\", err)\n\t\t}\n\t\treturn nil, fmt.Errorf(\"preprocessed profile missing header\")\n\t}\n\tif gotHdr := scanner.Text() + \"\\n\"; gotHdr != serializationHeader {\n\t\treturn nil, fmt.Errorf(\"preprocessed profile malformed header; got %q want %q\", gotHdr, serializationHeader)\n\t}\n\n\tfor scanner.Scan() {\n\t\treadStr := scanner.Text()\n\n\t\tcallerName := readStr\n\n\t\tif !scanner.Scan() {\n\t\t\tif err := scanner.Err(); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"error reading preprocessed profile: %w\", err)\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"preprocessed profile entry missing callee\")\n\t\t}\n\t\tcalleeName := scanner.Text()\n\n\t\tif !scanner.Scan() {\n\t\t\tif err := scanner.Err(); err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"error reading preprocessed profile: %w\", err)","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/internal/pgo/deserialize.go#L27-L63","documentation":"FromSerialized read the first line successfully but it does not equal serializationHeader. The stream therefore starts with content that is not a serialized PGO profile — most often a raw pprof or a plain text profile passed to the wrong parser.","triggerScenarios":"First line of the reader, after appending a newline, differs from serializationHeader.","commonSituations":"User passes a raw pprof file (protobuf) to FromSerialized instead of a profile produced by Profile.WriteTo, or passes a textual CPU profile from an unrelated tool.","solutions":["Feed FromSerialized only profiles written by Profile.WriteTo (the serialized format).","For raw pprof files, use the appropriate pprof parser, not FromSerialized.","Call IsSerialized first to confirm the format before parsing."],"exampleFix":"// before: raw pprof fed to the serialized parser\nprof, err := pgo.FromSerialized(file)\n\n// after: confirm format first\nif ok, _ := pgo.IsSerialized(bufReader); !ok {\n    return errors.New(\"not a serialized PGO profile; parse as pprof instead\")\n}\nprof, err := pgo.FromSerialized(bufReader)","handlingStrategy":"validation","validationCode":"// Confirm the serialized header before parsing.\n// ok, err := pgo.IsSerialized(bufReader)\n// if err != nil { return err }\n// if !ok { return errors.New(\"not a serialized PGO profile; use the pprof parser instead\") }","typeGuard":null,"tryCatchPattern":"// prof, err := pgo.FromSerialized(r)\n// if err != nil && strings.Contains(err.Error(), \"malformed header\") {\n//     // wrong format (e.g. raw pprof); route to the correct parser\n//     return err\n// }","preventionTips":["Only pass profiles produced by Profile.WriteTo to FromSerialized.","Use the dedicated pprof parser for raw pprof data.","Validate with IsSerialized first."],"tags":["pgo","profile","format","deserialize"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}