gohugoio/hugo · error
failed to create CPU profile
Error message
failed to create CPU profile: %w
What it means
Hugo's `hugoBuilder.initCPUProfile` calls `os.Create(c.r.cpuprofile)` to open the output file for a Go CPU profile (set via `--cpuprofile`). This error wraps the OS-level file creation failure. It fires before any profiling starts, so the process has not yet begun capturing samples.
Solutions
- Verify the parent directory exists and is writable, then re-run `hugo --cpuprofile=<abs/path/cpu.prof>`.
- Use an absolute path under a directory you own (e.g. `~/cpu.prof`) instead of a bare filename.
- Drop `--cpuprofile` entirely if you do not need profiling — `initCPUProfile` is a no-op when the flag is empty.
Example fix
// before // $ hugo --cpuprofile=/var/run/cpu.prof // after // $ mkdir -p /tmp/hugoprof && hugo --cpuprofile=/tmp/hugoprof/cpu.prof
Defensive patterns
Strategy: validation
Validate before calling
// Validate writability before launching Hugo with --cpuprofile.
import (
"os"
"path/filepath"
)
func validateProfilePath(p string) error {
dir := filepath.Dir(p)
info, err := os.Stat(dir)
if err != nil { return err }
if !info.IsDir() { return os.ErrNotExist }
// probe writability
f, err := os.CreateTemp(dir, ".hugocpu-*")
if err != nil { return err }
f.Close(); os.Remove(f.Name())
return nil
} Type guard
null
Try / catch
null
Prevention
- Always pass an absolute `--cpuprofile` path under a writable directory you own.
- Pre-flight check that the parent directory exists before running `hugo --cpuprofile`.
- Leave the flag unset during normal builds to skip profiling entirely.
When it happens
Trigger: Invoked when `c.r.cpuprofile != ""` (the `--cpuprofile` flag was passed) and `os.Create` returns a non-nil error — e.g. a directory in the path does not exist, the path is read-only, or the user lacks write permission.
Common situations: Passing a relative `--cpuprofile=cpu.prof` from a working directory that is not writable; pointing the flag at an unwritable or non-existent directory like `/var/log/cpu.prof`; a typo in the path including a missing parent directory.
Related errors
- abort: jekyll root contains neither posts nor drafts
- failed to create trace file
- failed to start CPU profile
- is not a directory
- must not be run from the file system root
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/2989d35e3f3f3773.
Report an issue: GitHub.
Appendix: source
Thrown at commands/hugobuilder.go:179
// getDirList provides NewWatcher() with a list of directories to watch for changes.
func (c *hugoBuilder) getDirList() ([]string, error) {
h, err := c.hugo()
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 {View on GitHub (pinned to 52c9bd7908)