golang/go · error

preprocessed profile missing header

Error message

preprocessed profile missing header

What it means

FromSerialized's first scanner.Scan() returned false with no scanner error, meaning the stream is empty (no header line at all). A valid serialized PGO profile must begin with the serialization header line, so an empty file is rejected.

Source

Thrown at src/cmd/internal/pgo/deserialize.go:42

	} else if err != nil {
		return false, fmt.Errorf("error reading profile header: %w", err)
	}

	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()

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Regenerate the profile so it actually contains serialized data.
  2. Verify the profile path is correct and the file is non-empty.
  3. Guard with IsSerialized first to distinguish 'empty' from 'wrong format'.

Example fix

// before
prof, err := pgo.FromSerialized(bytes.NewReader(nil))

// after: validate before parsing
ok, err := pgo.IsSerialized(bufReader)
if err != nil { return err }
if !ok { return errors.New("profile is empty or not serialized") }
prof, err := pgo.FromSerialized(bufReader)
Defensive patterns

Strategy: validation

Validate before calling

// Distinguish empty from wrong-format up front.
// ok, err := pgo.IsSerialized(bufio.NewReader(bytes.NewReader(data)))
// if err != nil { return err }
// if !ok { return errors.New("profile is empty or not a serialized PGO profile") }

Try / catch

// prof, err := pgo.FromSerialized(r)
// if err != nil {
//     if err.Error() == "preprocessed profile missing header" {
//         // empty input; check the file path/size
//     }
//     return err
// }

Prevention

When it happens

Trigger: Passing an empty (zero-byte) or whitespace-only reader to FromSerialized.

Common situations: Pointing -pgoprofile (or a tool's profile input) at an empty file, a file path that was created but never written, or a truncated-to-zero profile.

Related errors


AI-assisted analysis of golang/go@b6b368adc5 (2026-08-12). Data as JSON: /api/errors/33d526e419de417f. Report an issue: GitHub.