golang/go · error
preprocessed profile malformed header; got %q want %q
Error message
preprocessed profile malformed header; got %q want %q
What it means
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.
Source
Thrown at src/cmd/internal/pgo/deserialize.go:45
return string(hdr) == serializationHeader, nil
}
// FromSerialized parses a profile from serialization output of Profile.WriteTo.
func FromSerialized(r io.Reader) (*Profile, error) {
d := emptyProfile()
scanner := bufio.NewScanner(r)
scanner.Split(bufio.ScanLines)
if !scanner.Scan() {
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("error reading preprocessed profile: %w", err)
}
return nil, fmt.Errorf("preprocessed profile missing header")
}
if gotHdr := scanner.Text() + "\n"; gotHdr != serializationHeader {
return nil, fmt.Errorf("preprocessed profile malformed header; got %q want %q", gotHdr, serializationHeader)
}
for scanner.Scan() {
readStr := scanner.Text()
callerName := readStr
if !scanner.Scan() {
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("error reading preprocessed profile: %w", err)
}
return nil, fmt.Errorf("preprocessed profile entry missing callee")
}
calleeName := scanner.Text()
if !scanner.Scan() {
if err := scanner.Err(); err != nil {
return nil, fmt.Errorf("error reading preprocessed profile: %w", err)View on GitHub (pinned to b6b368adc5)
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.
Example fix
// before: raw pprof fed to the serialized parser
prof, err := pgo.FromSerialized(file)
// after: confirm format first
if ok, _ := pgo.IsSerialized(bufReader); !ok {
return errors.New("not a serialized PGO profile; parse as pprof instead")
}
prof, err := pgo.FromSerialized(bufReader) Defensive patterns
Strategy: validation
Validate before calling
// Confirm the serialized header before parsing.
// ok, err := pgo.IsSerialized(bufReader)
// if err != nil { return err }
// if !ok { return errors.New("not a serialized PGO profile; use the pprof parser instead") } Try / catch
// prof, err := pgo.FromSerialized(r)
// if err != nil && strings.Contains(err.Error(), "malformed header") {
// // wrong format (e.g. raw pprof); route to the correct parser
// return err
// } Prevention
- Only pass profiles produced by Profile.WriteTo to FromSerialized.
- Use the dedicated pprof parser for raw pprof data.
- Validate with IsSerialized first.
When it happens
Trigger: First line of the reader, after appending a newline, differs from serializationHeader.
Common situations: 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.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- error reading profile header: %w
- error reading preprocessed profile: %w
- preprocessed profile missing header
- preprocessed profile entry missing callee
- error opening target for caching: %w
AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12).
Data as JSON: /api/errors/bbe6d0516b11642e.
Report an issue: GitHub.