hashicorp/nomad · error

failed to create stdout: %v

Error message

failed to create stdout: %v

What it means

ExecCommand.Stdout() lazily opens a FIFO writer at StdoutPath (when set and not /dev/null) so the parent can stream task stdout into the pipe. If fifo.OpenWriter fails (FIFO missing, not yet created, or permission denied) the error is wrapped with this message and Launch aborts.

Source

Thrown at drivers/shared/executor/executor.go:269

// GetWriters returns the unexported io.WriteCloser for the stdout and stderr
// handles. This is mainly used for unit testing purposes.
func (c *ExecCommand) GetWriters() (stdout io.WriteCloser, stderr io.WriteCloser) {
	return c.stdout, c.stderr
}

type nopCloser struct {
	io.Writer
}

func (nopCloser) Close() error { return nil }

// Stdout returns a writer for the configured file descriptor
func (c *ExecCommand) Stdout() (io.WriteCloser, error) {
	if c.stdout == nil {
		if c.StdoutPath != "" && c.StdoutPath != os.DevNull {
			f, err := fifo.OpenWriter(c.StdoutPath)
			if err != nil {
				return nil, fmt.Errorf("failed to create stdout: %v", err)
			}
			c.stdout = f
		} else {
			c.stdout = nopCloser{io.Discard}
		}
	}
	return c.stdout, nil
}

// Stderr returns a writer for the configured file descriptor
func (c *ExecCommand) Stderr() (io.WriteCloser, error) {
	if c.stderr == nil {
		if c.StderrPath != "" && c.StderrPath != os.DevNull {
			f, err := fifo.OpenWriter(c.StderrPath)
			if err != nil {
				return nil, fmt.Errorf("failed to create stderr: %v", err)
			}
			c.stderr = f

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Check the fifo path exists and is a pipe: ls -l /proc/<alloc-dir>/... ; restart the allocation to recreate it
  2. Fix directory/ACL permissions so the executor user can open the fifo for writing
  3. Review SELinux/apparmor denials in audit logs
  4. Check the wrapped %v message: ENOENT means the fifo wasn't created; EACCES means permissions

Example fix

// before
// drwx------ alloc-dir (executor user cannot reach fifo)
// after
// chown -R nomad:nomad alloc-dir && chmod 750 alloc-dir
Defensive patterns

Strategy: try-catch

Validate before calling

func stdoutFifoReady(path string) error {
  fi, err := os.Stat(path)
  if err != nil { return fmt.Errorf("stdout fifo missing: %w", err) }
  if fi.Mode()&os.ModeNamedPipe == 0 { return fmt.Errorf("%s is not a fifo", path) }
  if fi.Mode().Perm()&0o200 == 0 { return fmt.Errorf("%s not writable", path) }
  return nil
}

Try / catch

if err := launchTask(); err != nil {
  if strings.Contains(err.Error(), "failed to create stdout") {
    log.Printf("stdout fifo broken, restarting alloc: %v", err)
    return restartAllocation()
  }
  return err
}

Prevention

When it happens

Trigger: Launch() calls command.Stdout() and fifo.OpenWriter(c.StdoutPath) errors — the named pipe does not exist, was deleted, or the executor user lacks write permission.

Common situations: Task stdout fifo cleaned up too early by a prior failed launch, /tmp or data dir permissions changed, SELinux/apparmor blocking fifo open, exec task running as different UID than the client that created the fifo.

Related errors


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