gohugoio/hugo · error

data: failed to open %q: %w

Error message

data: failed to open %q: %w

What it means

Returned from HugoSites.handleDataFile in hugolib/hugo_sites.go when a file discovered while walking the data/ filesystem cannot be opened for reading. This happens before parsing — it is a filesystem-level failure (permissions, broken symlink, file vanished between walk and open) on the composite data filesystem that overlays project, themes, and module mounts.

Source

Thrown at hugolib/hugo_sites.go:729

				if pi == nil {
					panic("no path info")
				}
				return h.handleDataFile(source.NewFileInfo(fi))
			},
		})

	if err := w.Walk(); err != nil {
		return err
	}
	return nil
}

func (h *HugoSites) handleDataFile(r *source.File) error {
	var current map[string]any

	f, err := r.FileInfo().Meta().Open()
	if err != nil {
		return fmt.Errorf("data: failed to open %q: %w", r.LogicalName(), err)
	}
	defer f.Close()

	// Crawl in data tree to insert data
	current = h.data
	dataPath := r.FileInfo().Meta().PathInfo.Unnormalized().Dir()[1:]
	keyParts := strings.SplitSeq(dataPath, "/")

	for key := range keyParts {
		if key != "" {
			if _, ok := current[key]; !ok {
				current[key] = make(map[string]any)
			}
			current = current[key].(map[string]any)
		}
	}

	data, err := h.readData(r)

View on GitHub ↗ (pinned to 8a468df065)

Solutions

  1. Identify the file from the quoted name in the error and check it exists and is readable: `ls -l data/<file>` and fix permissions (`chmod +r`).
  2. If it's a symlink, verify the target exists; replace broken symlinks with real files or correct the link.
  3. In Docker/CI, ensure the build user owns or can read the mounted source tree (adjust COPY --chown or volume mount options).
  4. If the file is legitimately gone, remove the stale reference/mount and rebuild.
Defensive patterns

Strategy: try-catch

Validate before calling

if _, err := os.Stat(filepath.Join("data", name)); err != nil {
    return fmt.Errorf("data file missing/unreadable: %w", err)
}

Type guard

func isDataOpenErr(err error) bool {
    var pe *fs.PathError
    return errors.As(err, &pe) || errors.Is(err, fs.ErrNotExist) || errors.Is(err, fs.ErrPermission)
}

Try / catch

if err := h.Build(cfg); err != nil {
    if isDataOpenErr(err) {
        // filesystem-level failure opening a data file: check permissions, symlinks, mounts
    }
    return err
}

Prevention

When it happens

Trigger: The data-directory walk finds a file whose Meta().Open() fails: a symlink in data/ pointing to a nonexistent target, a file without read permission for the build user, a file deleted mid-build (e.g. by a concurrent process while `hugo server` rebuilds), or a module-mounted path that resolved but is unreadable.

Common situations: Docker/CI builds where data files are owned by a different UID or volume-mounted with restrictive permissions; symlinked data directories after a repo checkout without symlink support (common on Windows); cloud-synced folders (Dropbox/OneDrive) holding placeholder files; module mounts referencing paths outside the checked-out tree.

Related errors


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