golang/go · error

error writing output file: %w

Error message

error writing output file: %w

What it means

The `preprofile` tool created the output file but failed while writing the preprocessed PGO data to it via `d.WriteTo(w)`. This occurs after the output file is opened and a `bufio.Writer` is wrapping it. The error could be from the serialization itself or from the underlying writer (disk full, broken pipe, I/O error).

Source

Thrown at src/cmd/preprofile/main.go:62

	d, err := pgo.FromPProf(r)
	if err != nil {
		return fmt.Errorf("error parsing profile: %w", err)
	}

	var out *os.File
	if outputFile == "" {
		out = os.Stdout
	} else {
		out, err = os.Create(outputFile)
		if err != nil {
			return fmt.Errorf("error creating output file: %w", err)
		}
		defer out.Close()
	}

	w := bufio.NewWriter(out)
	if _, err := d.WriteTo(w); err != nil {
		return fmt.Errorf("error writing output file: %w", err)
	}

	return nil
}

func main() {
	objabi.AddVersionFlag()

	log.SetFlags(0)
	log.SetPrefix("preprofile: ")
	counter.Open()

	flag.Usage = usage
	flag.Parse()
	counter.Inc("preprofile/invocations")
	counter.CountFlags("preprofile/flag:", *flag.CommandLine)
	if *input == "" {
		log.Print("Input pprof path required (-i)")

View on GitHub (pinned to b6b368adc5)

Solutions

  1. Check available disk space: `df -h` — the PGO intermediate file can be large for complex profiles.
  2. If writing to a network filesystem, try writing to local storage first and then copying.
  3. Check for disk quotas: `quota -u $USER` on systems that enforce them.
  4. If writing to a pipe (stdout), ensure the consuming process reads all data before exiting.
  5. Look at the underlying error (the `%w` wraps it) for the specific I/O failure reason.

Example fix

# Before: disk full or pipe broken during write
go tool preprofile -i cpu.prof -o /full/disk/output

# After: write to local storage with sufficient space
df -h /tmp  # verify space
go tool preprofile -i cpu.prof -o /tmp/pgo_output

# If piping, ensure consumer reads all data:
go tool preprofile -i cpu.prof | head -c 999999999  # avoid early close
Defensive patterns

Strategy: try-catch

Validate before calling

// Check disk space before writing large PGO output
var stat syscall.Statfs_t
if err := syscall.Statfs(outputDir, &stat); err == nil {
    availBytes := stat.Bavail * uint64(stat.Bsize)
    if availBytes < 100*1024*1024 {
        log.Printf("Warning: only %d MB free; PGO output may fail", availBytes/1024/1024)
    }
}

Try / catch

// In build system wrapper:
//   err := preprocess(profileFile, outputFile)
//   if err != nil {
//       if strings.Contains(err.Error(), "error writing output") {
//           // Check disk space, retry to alternate location
//           outputFile = filepath.Join(os.TempDir(), filepath.Base(outputFile))
//           err = preprocess(profileFile, outputFile)
//       }
//   }

Prevention

When it happens

Trigger: Fires at preprofile/main.go:61-62 when `d.WriteTo(w)` returns an error, where `w` is a `bufio.Writer` wrapping either `os.Stdout` or the created output file. Note: the bufio writer's `Flush` is not explicitly called before close, so a flush failure during `Close` of the deferred file handle could also surface related issues.

Common situations: Disk ran out of space mid-write. Writing to stdout where the downstream consumer closed the pipe early (broken pipe). I/O error on the underlying storage device. The PGO data structure is unexpectedly large (very complex profiles). Filesystem quota exceeded. Network filesystem timeout during write.

Related errors


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