gohugoio/hugo · error

failed to start CPU profile

Error message

failed to start CPU profile: %w

What it means

After the CPU profile file is created, Hugo calls `pprof.StartCPUProfile(f)`. This error wraps a failure from the Go runtime profiler, which most commonly occurs when profiling is already active in the current process. The created file is closed before returning the error.

Solutions

  1. Ensure only one component in the process calls CPU profiling; remove or guard the other `pprof.StartCPUProfile` call.
  2. Run `hugo` as a standalone process instead of embedding it where profiling is already active.
  3. Omit `--cpuprofile` if profiling is being handled elsewhere.

Example fix

// before
pprof.StartCPUProfile(f) // elsewhere in host app, still active
// ...
hugo.Build(...) // also sets --cpuprofile
// after
pprof.StopCPUProfile() // stop the first profiler before building
Defensive patterns

Strategy: try-catch

Validate before calling

// Ensure no other CPU profiler is active before invoking Hugo.
// (pprof exposes no public IsRunning; track it in your host process.)
var cpuProfilingActive bool
func safeStartCPUProfile(f *os.File) error {
  if cpuProfilingActive { return fmt.Errorf("cpu profile already active") }
  if err := pprof.StartCPUProfile(f); err != nil { return err }
  cpuProfilingActive = true
  return nil
}

Type guard

null

Try / catch

// Wrap the Hugo build call and surface the profiling conflict cleanly.
err := hugo.Build(cfg)
if err != nil && strings.Contains(err.Error(), "failed to start CPU profile") {
  // resolve the host-process profiler conflict, then retry without --cpuprofile
}

Prevention

When it happens

Trigger: Triggered when `pprof.StartCPUProfile` returns non-nil — classically because another goroutine/component already started CPU profiling, or the runtime reports it cannot configure the profiler on this platform.

Common situations: Running Hugo embedded inside a larger Go binary that already invoked `pprof.StartCPUProfile`; a test harness or shared library that starts profiling before Hugo's `initProfiling` runs; re-entrant invocation.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/f0f3e56881b0cd6c. Report an issue: GitHub.

Appendix: source

Thrown at commands/hugobuilder.go:183

	if err != nil {
		return nil, err
	}

	return hstrings.UniqueStringsSorted(h.PathSpec.BaseFs.WatchFilenames()), nil
}

func (c *hugoBuilder) initCPUProfile() (func(), error) {
	if c.r.cpuprofile == "" {
		return nil, nil
	}

	f, err := os.Create(c.r.cpuprofile)
	if err != nil {
		return nil, fmt.Errorf("failed to create CPU profile: %w", err)
	}
	if err := pprof.StartCPUProfile(f); err != nil {
		f.Close()
		return nil, fmt.Errorf("failed to start CPU profile: %w", err)
	}
	return func() {
		pprof.StopCPUProfile()
		f.Close()
	}, nil
}

func (c *hugoBuilder) initMemProfile() {
	if c.r.memprofile == "" {
		return
	}

	f, err := os.Create(c.r.memprofile)
	if err != nil {
		c.r.logger.Errorf("could not create memory profile: ", err)
	}
	defer f.Close()
	runtime.GC() // get up-to-date statistics

View on GitHub (pinned to 52c9bd7908)