containerd/containerd · error

stat %s: %w

Error message

stat %s: %w

What it means

wrapUserFile wraps a user-supplied fs.File (e.g. a user-supplied passwd/group file source) and first stats it; if Stat fails the file is closed and this error wraps the stat failure with the file name. The library cannot determine the file's size/mode, so it refuses to read it. It prevents later mis-parsing of unusable file sources.

Source

Thrown at pkg/oci/spec_opts.go:1876

	if err != nil {
		return nil, err
	}
	return wrapUserFile(f, name)
}

// maxUserFileBytes caps how much data is read from any user-database file
// opened via openUserFile. Real systems keep these files well under 1 MiB;
// 10 MiB is generous headroom while keeping peak memory during
// user.ParsePasswd/ParseGroup bounded to single-digit MiB.
const maxUserFileBytes = 10 << 20

// wrapUserFile rejects non-regular sources and returns an fs.File that
// errors out if more than maxUserFileBytes are read from it.
func wrapUserFile(f fs.File, name string) (fs.File, error) {
	info, err := f.Stat()
	if err != nil {
		f.Close()
		return nil, fmt.Errorf("stat %s: %w", name, err)
	}
	if !info.Mode().IsRegular() {
		f.Close()
		return nil, fmt.Errorf("%s is not a regular file", name)
	}
	return &limitedFile{
		File: f,
		// Allow one byte past the cap so an overflow surfaces as an
		// error rather than a silent EOF that the parser would treat as
		// a clean end-of-file (and miss any entries past the cap).
		r:    &io.LimitedReader{R: f, N: maxUserFileBytes + 1},
		name: name,
	}, nil
}

// limitedFile is an fs.File whose Read returns an error once more than
// maxUserFileBytes have been read.
type limitedFile struct {

View on GitHub (pinned to 4246446a2b)

Solutions

  1. Check the wrapped error to see why Stat failed and fix the underlying FS/permissions.
  2. Verify the file exists in the provided fs.FS before calling the spec option.
  3. Provide the file via a regular os file path if the custom FS is unreliable.
  4. Ensure the fs.File implementation returns valid Stat info for regular files.

Example fix

// before
f, err := customFS.Open("etc/passwd") // stat fails later
// after
if _, err := fs.Stat(customFS, "etc/passwd"); err != nil {
  return fmt.Errorf("user file missing: %w", err)
}
Defensive patterns

Strategy: validation

Validate before calling

if _, err := fs.Stat(userFS, "etc/passwd"); err != nil {
  return fmt.Errorf("user source unavailable: %w", err)
}

Try / catch

if err != nil {
  if strings.Contains(err.Error(), "stat ") {
    // fall back to a plain os file source
  }
}

Prevention

When it happens

Trigger: Passing a custom fs.FS / io/fs.File source to spec-opt parsers like WithCustomUser (or etc/passwd overrides) where calling Stat() on the opened file returns an error — e.g. the file was deleted, the custom FS errors, or permissions deny access.

Common situations: Custom embed.FS or memfs missing the entry; a network-backed FS returning stat errors; symlink loops or permission-denied paths in a custom resolver.

Related errors


AI-assisted analysis of containerd/containerd@4246446a2b (2026-09-02). Data as JSON: /api/errors/93b0eacc5b5e1fbe. Report an issue: GitHub.