gohugoio/hugo · error
walk: Readdir
Error message
walk: Readdir: %w
What it means
Emitted by Walkway.walk when ReadDirWithContext fails while enumerating a directory's entries after it was successfully opened. Distinct from the open error (302): the directory opened fine but reading its contents errored. Wrapped as 'walk: Readdir: %w'.
Solutions
- Unwrap the %w to get the concrete ReadDir error and act on its syscall code (EIO vs ENOENT vs EACCES).
- Reduce the directory's entry count or restructure into subdirectories if an fs limit is hit.
- For overlay/remote mounts, retry the build or mount the directory from a stable local source.
- Confirm the directory still exists and is readable on the underlying filesystem after the build fails.
Defensive patterns
Strategy: retry
Try / catch
err := walkway.Walk()
if err != nil && strings.Contains(err.Error(), "walk: Readdir:") {
var perr *fs.PathError
if errors.As(errors.Unwrap(err), &perr) && isTransient(perr.Err) { /* retry once */ }
} Prevention
- Keep walked directories on stable local storage; avoid flaky remote mounts.
- Split oversized directories to stay under fs-specific listing limits.
- Retry the build once for transient I/O; investigate if it persists.
When it happens
Trigger: An I/O error partway through reading a large directory (EIO), an afero backing store that fails listing (e.g. a remote/overlay fs whose list RPC errors), or an underlying ReadDir returning a non-nil, non-EOF error. The file is Closed immediately after, so the error propagates from ReadDirWithContext.
Common situations: Network/overlay filesystem flakiness on a content or assets mount; a directory with an enormous entry count hitting an fs-specific limit; a corrupt directory entry; concurrent removal of the directory's inode after Open but before full read.
Related errors
AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09).
Data as JSON: /api/errors/f417297cb828b2ac.
Report an issue: GitHub.
Appendix: source
Thrown at hugofs/walk.go:172
}
if dirEntries == nil {
f, err := w.cfg.Fs.Open(path)
if err != nil {
if w.checkErr(path, err) {
return nil
}
return fmt.Errorf("walk: open: path: %q filename: %q: %s", path, info.Meta().Filename, err)
}
fis, newCtx, err := ReadDirWithContext(ctx, f, -1)
ctx = newCtx
f.Close()
if err != nil {
if w.checkErr(path, err) {
return nil
}
return fmt.Errorf("walk: Readdir: %w", err)
}
dirEntries = DirEntriesToFileMetaInfos(fis)
for _, fi := range dirEntries {
if fi.Meta().PathInfo == nil {
fi.Meta().PathInfo = w.cfg.PathParser.Parse("", filepath.Join(pathRel, fi.Name()))
}
}
if w.cfg.SortDirEntries {
sort.Slice(dirEntries, func(i, j int) bool {
return dirEntries[i].Name() < dirEntries[j].Name()
})
}
}
if w.cfg.IgnoreFile != nil {View on GitHub (pinned to 52c9bd7908)