gohugoio/hugo · error

walk: stat: %s

Error message

walk: stat: %s

What it means

Walkway.walk traverses Hugo's virtual filesystem (content, static, assets, module mounts). When it needs a FileInfo for the current path and Fs.Stat fails with anything other than a tolerated not-exist error, it wraps the failure as "walk: stat: ...". Not-exist on the walk root, or not-exist while FailOnNotExist is off, is silently skipped/warned; other stat errors abort the walk and typically fail the build.

Source

Thrown at hugofs/walk.go:139

	return false
}

// walk recursively descends path, calling walkFn.
func (w *Walkway) walk(ctx context.Context, path string, info FileMetaInfo, dirEntries []FileMetaInfo) error {
	pathRel := strings.TrimPrefix(path, w.cfg.Root)

	if info == nil {
		var err error
		fi, err := w.cfg.Fs.Stat(path)
		if err != nil {
			if path == w.cfg.Root && herrors.IsNotExist(err) {
				return nil
			}
			if w.checkErr(path, err) {
				return nil
			}
			return fmt.Errorf("walk: stat: %s", err)
		}
		info = fi.(FileMetaInfo)
	}

	err := w.cfg.WalkFn(ctx, path, info)
	if err != nil {
		if info.IsDir() && err == filepath.SkipDir {
			return nil
		}
		return err
	}

	if !info.IsDir() {
		return nil
	}

	if dirEntries == nil {
		f, err := w.cfg.Fs.Open(path)

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Read the wrapped error: for permission denied, fix ownership/permissions of the reported path (common in Docker/CI mounts).
  2. For dangling symlinks under content/static/assets, remove or fix the link target.
  3. If files are being removed during watch rebuilds by a sync tool, exclude its temp files or re-run the build.
Defensive patterns

Strategy: validation

Validate before calling

if _, err := os.Stat(root); err != nil {
	// root missing or unreadable — fix path/permissions before walking
	return err
}

Try / catch

err := w.Walk()
if err != nil {
	// stat failed on the walk root; use errors.Is(err, fs.ErrNotExist) / fs.ErrPermission to distinguish
}

Prevention

When it happens

Trigger: Fs.Stat(path) returning a non-IsNotExist error during directory walking — permission denied on a content/static/asset directory, I/O errors, broken symlinks pointing into unreadable locations, or a file removed/replaced mid-walk when FailOnNotExist is set.

Common situations: Building as a user without read permission on part of the project (Docker/CI volume permissions), network or overlay filesystems returning transient errors, symlinked content directories with dangling or unreadable targets, and files being deleted by another process (editor, sync tool) during `hugo server` rebuilds.

Related errors


AI-assisted analysis of gohugoio/hugo@8a468df065 (2026-07-31). Data as JSON: /data/errors/32dbb48e15ef4880.json. Report an issue: GitHub ↗.