hashicorp/nomad · error

error opening fifo parent directory %q: %v

Error message

error opening fifo parent directory %q: %v

What it means

This mkfifo variant creates FIFOs safely with mkfifoat: it first opens the FIFO's parent directory with os.OpenRoot so the create happens relative to a directory handle (no symlink escape). This error is returned when that parent-directory open fails — the directory does not exist (ENOENT) or is not accessible (EACCES).

Source

Thrown at client/lib/fifo/mkfifoat.go:22

//go:build linux || freebsd || netbsd || openbsd

package fifo

import (
	"fmt"
	"os"
	"path/filepath"

	"golang.org/x/sys/unix"
)

func mkfifo(path string, mode uint32) (err error) {
	dir := filepath.Dir(path)
	base := filepath.Base(path)

	root, err := os.OpenRoot(dir)
	if err != nil {
		return fmt.Errorf("error opening fifo parent directory %q: %v", dir, err)
	}
	defer root.Close()

	parent, err := root.Open(".")
	if err != nil {
		return fmt.Errorf("error getting file handle to fifo parent directory %q: %v", dir, err)
	}
	defer parent.Close()

	// os.Root doesn't support creating a FIFO, so we need to drop to the
	// syscall and grab the parent's FD
	err = unix.Mkfifoat(int(parent.Fd()), base, mode)
	if err != nil {
		return fmt.Errorf("error creating fifo: %w", err)
	}
	return nil
}

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Create the parent directory first: os.MkdirAll(filepath.Dir(path), 0o700)
  2. Verify the directory exists and is writable/searchable by the current user
  3. Fix the configured FIFO path
  4. Check for symlinked parent components that os.Root intentionally refuses to follow

Example fix

// before
if err := fifo.Create("/run/containerd/io/stdout", 0o600); err != nil { return err }
// after
if err := os.MkdirAll("/run/containerd/io", 0o700); err != nil { return err }
if err := fifo.Create("/run/containerd/io/stdout", 0o600); err != nil { return err }
Defensive patterns

Strategy: validation

Validate before calling

dir := filepath.Dir(path)
if fi, err := os.Stat(dir); err != nil || !fi.IsDir() {
	return fmt.Errorf("fifo parent dir %q missing", dir)
}

Try / catch

err := fifo.Create(path, mode)
if err != nil {
	if errors.Is(err, fs.ErrNotExist) {
		if mkErr := os.MkdirAll(filepath.Dir(path), 0o700); mkErr != nil { return mkErr }
		err = fifo.Create(path, mode)
	}
	if err != nil { return err }
}

Prevention

When it happens

Trigger: Calling fifo.Create(path, mode) on Linux when filepath.Dir(path) does not exist, the process lacks search permission on the directory, or the directory path is invalid/unmounted.

Common situations: Log IO setup before the runtime directory is created; typo in configured path; permission drops (container running as non-root user in root-owned dir); path traversal blocked because parent is a symlink to elsewhere.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/821eba518988d95a. Report an issue: GitHub.