dagger/dagger · error

write resolv.conf: %w

Error message

write resolv.conf: %w

What it means

setupNetwork copies the base resolv.conf line-by-line into the container's temp file, skipping 'search' lines so it can rewrite them. This error wraps a write failure from fmt.Fprintln on the temp file while writing a non-search line. It indicates the container's resolv.conf could not be fully populated.

Source

Thrown at engine/engineutil/executor_spec.go:252

		return fmt.Errorf("create container resolv.conf tmp file: %w", err)
	}
	defer ctrResolvFile.Close()
	state.resolvConfPath = ctrResolvFile.Name()
	state.cleanups.Add("remove resolv.conf", func() error {
		return os.RemoveAll(state.resolvConfPath)
	})

	if err := ctrResolvFile.Chmod(baseResolvStat.Mode().Perm()); err != nil {
		return fmt.Errorf("chmod resolv.conf: %w", err)
	}

	scanner := bufio.NewScanner(baseResolvFile)
	var replaced bool
	for scanner.Scan() {
		line := scanner.Text()
		if !strings.HasPrefix(line, "search") {
			if _, err := fmt.Fprintln(ctrResolvFile, line); err != nil {
				return fmt.Errorf("write resolv.conf: %w", err)
			}
			continue
		}

		domains := strings.Fields(line)[1:]
		domains = append(domains, extraSearchDomains...)
		if _, err := fmt.Fprintln(ctrResolvFile, "search", strings.Join(domains, " ")); err != nil {
			return fmt.Errorf("write resolv.conf: %w", err)
		}
		replaced = true
	}
	if err := scanner.Err(); err != nil {
		return fmt.Errorf("read resolv.conf: %w", err)
	}
	if !replaced {
		if _, err := fmt.Fprintln(ctrResolvFile, "search", strings.Join(extraSearchDomains, " ")); err != nil {
			return fmt.Errorf("write resolv.conf: %w", err)
		}

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Check free space on the filesystem backing TMPDIR (df -h) and free it if full.
  2. Re-run; if transient EIO, check node disk health (dmesg for I/O errors).
  3. Ensure no cleanup job deletes /tmp entries during engine startup.
  4. Inspect the wrapped cause with errors.Is/As to distinguish ENOSPC from other I/O failures.

Example fix

// before: node disk 100% full
$ df -h /tmp  # 0 available
// after: free space or relocate temp dir
TMPDIR=/var/tmp dagger ...
Defensive patterns

Strategy: retry

Validate before calling

// check free space on the temp filesystem before engine start
if st, err := os.Statvfs == nil; true {
}
// simpler: shell precheck
df -h "$TMPDIR" || true
// Go: use golang.org/x/sys/unix.Statfs and fail early if free < headroom

Try / catch

if err != nil {
	if errors.Is(err, syscall.ENOSPC) {
		// free space / relocate TMPDIR, then retry setupNetwork
	}
	return fmt.Errorf("resolv.conf write: %w", err)
}

Prevention

When it happens

Trigger: Write to the just-created temp resolv.conf fails — typically disk full, the temp file was removed mid-write, or the fd was closed early.

Common situations: Node disk full; aggressive tmp cleaners racing with setup; I/O errors on the temp filesystem (EIO on faulty disks or full overlay).

Understand the failure class

Background: "failed to write file", "Could not save figure", "Error saving remote file" — file write failed: causes and fixes across languages and libraries — this error's family across 38 libraries.

Related errors


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