dagger/dagger · error

open stdout file: %w

Error message

open stdout file: %w

What it means

setupStdio opens a dedicated stdout capture file (MetaMountStdoutPath) in the meta mount dir so the container's stdout is both streamed and persisted. If os.OpenFile fails, the whole stdio wiring fails and the exec is rejected with this wrapped OS error. It is distinct from the combined-output file: only the stdout path failed.

Source

Thrown at engine/engineutil/executor_spec.go:703

	if state.metaMountDirPath == "" {
		return nil
	}

	combinedOutputPath := filepath.Join(state.metaMountDirPath, MetaMountCombinedOutputPath)
	combinedOutputFile, err := os.OpenFile(combinedOutputPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600)
	if err != nil {
		return fmt.Errorf("open combined output file: %w", err)
	}
	state.cleanups.Add("close container combined output file", combinedOutputFile.Close)

	var stdoutWriters []io.Writer
	if state.procInfo.Stdout != nil {
		stdoutWriters = append(stdoutWriters, state.procInfo.Stdout)
	}
	stdoutPath := filepath.Join(state.metaMountDirPath, MetaMountStdoutPath)
	stdoutFile, err := os.OpenFile(stdoutPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600)
	if err != nil {
		return fmt.Errorf("open stdout file: %w", err)
	}
	state.cleanups.Add("close container stdout file", stdoutFile.Close)
	stdoutWriters = append(stdoutWriters, stdoutFile)
	stdoutWriters = append(stdoutWriters, combinedOutputFile)

	var stderrWriters []io.Writer
	if state.procInfo.Stderr != nil {
		stderrWriters = append(stderrWriters, state.procInfo.Stderr)
	}
	stderrPath := filepath.Join(state.metaMountDirPath, MetaMountStderrPath)
	stderrFile, err := os.OpenFile(stderrPath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600)
	if err != nil {
		return fmt.Errorf("open stderr file: %w", err)
	}
	state.cleanups.Add("close container stderr file", stderrFile.Close)
	stderrWriters = append(stderrWriters, stderrFile)
	stderrWriters = append(stderrWriters, combinedOutputFile)

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Free disk space on the engine data volume (df -h, prune with dagger query or docker system prune)
  2. Check and fix permissions/ownership of the engine meta mount directory
  3. Restart the engine so meta mount state is recreated cleanly
  4. Read the wrapped OS errno to target the exact cause (ENOSPC vs EACCES vs ENOENT)

Example fix

// before: 'open stdout file: no space left on device'
// after: prune and retry
$ df -h /var/lib/dagger
$ docker system prune -af && dagger engine restart
Defensive patterns

Strategy: validation

Validate before calling

// pre-flight on engine host
// df -h /var/lib/dagger && test -w /var/lib/dagger && echo ok

Try / catch

if err != nil && strings.Contains(err.Error(), "open stdout file") {
    // inspect wrapped errno: ENOSPC -> free disk, EACCES -> fix perms, then retry
}

Prevention

When it happens

Trigger: os.OpenFile(metaMountDirPath + MetaMountStdoutPath, O_CREATE|O_WRONLY|O_APPEND, 0600) errors during setupStdio — same class of causes as 4120 but on the stdout-specific path.

Common situations: ENOSPC on the engine host; meta mount directory permissions changed externally; SELinux/AppArmor denying writes to the engine data dir; partially deleted engine state after a crash.

Understand the failure class

Background: "open() failed", "failed to open file", "cannot create file" — what a file open error means and how to fix it — this error's family across 42 libraries.

Related errors


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/d02d130f10dc0ade. Report an issue: GitHub.