gohugoio/hugo · error

data: failed to open

Error message

data: failed to open %q: %w

What it means

Returned by handleDataFile() when opening a data file via its metadata Open() fails. The %q is the data file's logical name; %w is the I/O error. This is the per-file open failure during the data walk.

Solutions

  1. Inspect the %q filename and confirm the file exists and is readable at build time.
  2. Fix permissions on the data file and its parent directory.
  3. Exclude non-data files (binaries, temp files) from /data — move them elsewhere.
  4. If triggered by watch, do a clean full rebuild instead of relying on a partial update.

Example fix

# before: binary/backup file committed into /data
ls data/
# config.yaml  config.yaml~

# after: remove non-data artifacts
rm data/*~ data/*.bak
Defensive patterns

Strategy: validation

Validate before calling

// Filter /data to known data extensions before walking.
var dataExts = map[string]bool{"yaml":true,"yml":true,"json":true,"toml":true}
if !dataExts[ext(path)] { continue }

Try / catch

f, err := r.FileInfo().Meta().Open()
if err != nil {
    if errors.Is(err, fs.ErrPermission) || errors.Is(err, fs.ErrNotExist) {
        h.Log.Warnf("skip unreadable data file %q: %v", r.LogicalName(), err); return nil
    }
    return fmt.Errorf("data: failed to open %q: %w", r.LogicalName(), err)
}

Prevention

When it happens

Trigger: Raised at hugo_sites.go:729 when r.FileInfo().Meta().Open() returns an error while processing a walked data file — the file was enumerated by the walker but cannot be opened (race, permission, encoding, or it vanished).

Common situations: Data file deleted or replaced during the build (watch/CI race); non-UTF-8 or binary file placed in /data that the afero layer rejects; permission/ownership mismatch on /data files after a git checkout on a different OS.

Related errors


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

Appendix: 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 52c9bd7908)