golang/go · error

error processing profile header: %w

Error message

error processing profile header: %w

What it means

After opening the PGO profile file, the compiler calls pgo.IsSerialized to detect whether the profile is in Go's serialized format or standard pprof format by reading its header bytes. This error wraps any failure from that detection step, indicating the file is not a recognizable PGO profile.

Source

Thrown at src/cmd/compile/internal/pgoir/irgraph.go:132

	*pgo.Profile

	// WeightedCG represents the IRGraph built from profile, which we will
	// update as part of inlining.
	WeightedCG *IRGraph
}

// New generates a profile-graph from the profile or pre-processed profile.
func New(profileFile string) (*Profile, error) {
	f, err := os.Open(profileFile)
	if err != nil {
		return nil, fmt.Errorf("error opening profile: %w", err)
	}
	defer f.Close()
	r := bufio.NewReader(f)

	isSerialized, err := pgo.IsSerialized(r)
	if err != nil {
		return nil, fmt.Errorf("error processing profile header: %w", err)
	}

	var base *pgo.Profile
	if isSerialized {
		base, err = pgo.FromSerialized(r)
		if err != nil {
			return nil, fmt.Errorf("error processing serialized PGO profile: %w", err)
		}
	} else {
		base, err = pgo.FromPProf(r)
		if err != nil {
			return nil, fmt.Errorf("error processing pprof PGO profile: %w", err)
		}
	}

	if base.TotalWeight == 0 {
		return nil, nil // accept but ignore profile with no samples.
	}

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Regenerate the profile file from scratch with go test -cpuprofile=default.pgo
  2. Validate the file is a real pprof profile: go tool pprof default.pgo
  3. Ensure the profiling process completed without interruption or timeout
  4. Verify the file size is reasonable (a valid profile should be at least several KB)
Defensive patterns

Strategy: validation

Validate before calling

// Quick sanity check on a PGO profile file
func checkPGOProfile(path string) error {
    f, err := os.Open(path)
    if err != nil {
        return err
    }
    defer f.Close()
    header := make([]byte, 16)
    n, _ := f.Read(header)
    if n < 4 {
        return fmt.Errorf("file too small to be a valid profile")
    }
    // pprof profiles start with \x00\x00\x00 or a specific gzip header
    // Go serialized profiles have their own magic
    if header[0] != 0x1f && header[1] != 0x8b && header[0] != 0x00 {
        return fmt.Errorf("unrecognized profile format — regenerate with go test -cpuprofile")
    }
    return nil
}

Prevention

When it happens

Trigger: Passing a corrupt, truncated, or non-profile file as the PGO profile. Passing a plain text file, JSON, or a file with an unrecognized magic number. A profile file that was partially overwritten.

Common situations: Using a stale or truncated profile file. Pointing -pgo to the wrong file (e.g., a coverage profile instead of a CPU profile). File corruption during git operations or transfer between machines.

Related errors


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