ipfs/kubo · error

closing temp file: %w

Error message

closing temp file: %w

What it means

In `writeBinaryToTempFile`, a deferred closure surfaces a non-nil error from `f.Close()` only when no earlier error was set, wrapping it with this message. A failed close on the temp executable means buffered data may not have been handed to the OS and the file cannot be trusted; the path result is discarded and the temp file is removed.

Source

Thrown at core/commands/update.go:727

	if _, err := af.Write(data); err != nil {
		_ = af.Abort()
		return err
	}

	return af.Close()
}

// writeBinaryToTempFile writes data to a uniquely named executable file
// in the system temp directory and returns its path.
func writeBinaryToTempFile(data []byte, ver string) (path string, err error) {
	pattern := migrations.ExeName(fmt.Sprintf("ipfs-%s-*", ver))
	f, err := os.CreateTemp("", pattern)
	if err != nil {
		return "", fmt.Errorf("creating temp file: %w", err)
	}
	defer func() {
		if cerr := f.Close(); cerr != nil && err == nil {
			err = fmt.Errorf("closing temp file: %w", cerr)
		}
		if err != nil {
			os.Remove(f.Name())
		}
	}()

	if _, err = f.Write(data); err != nil {
		return "", fmt.Errorf("writing temp file: %w", err)
	}
	if err = f.Sync(); err != nil {
		return "", fmt.Errorf("syncing temp file: %w", err)
	}
	if err = f.Chmod(0o755); err != nil {
		return "", fmt.Errorf("chmod temp file: %w", err)
	}
	return f.Name(), nil
}

View on GitHub (pinned to 329838acdf)

Solutions

  1. Free disk space on the temp filesystem and retry: `df -h "$TMPDIR"`.
  2. Check for fd leaks/limits: `ulimit -n`, `ls /proc/self/fd | wc -l`; raise the soft limit if near it.
  3. Inspect `dmesg` for underlying storage errors on the temp filesystem.
  4. Simply rerun the update after the transient condition clears — the failed temp file is removed automatically.

Example fix

# before
ulimit -n 256
ipfs update install v0.30.0   # closing temp file: too many open files

# after
ulimit -n 4096
ipfs update install v0.30.0
Defensive patterns

Strategy: retry

Validate before calling

// raise fd headroom before long-running update wrappers
if n, _ := rlimit.Nofile(); n.Cur < 1024 {
	rlimit.SetNofile(1024) // or ulimit -n 4096 in shell
}

Try / catch

path, err := writeBinaryToTempFile(data, ver)
if err != nil {
	var perr *os.PathError
	if errors.As(err, &perr) && (errors.Is(perr.Err, syscall.EMFILE) || errors.Is(perr.Err, syscall.EIO)) {
		// transient: raise limits / wait for disk, then retry once
		return retryWithBackoff(updateOnce, 1)
	}
	return err
}

Prevention

When it happens

Trigger: `ipfs update` binary staging when closing the temp file fails: file descriptor exhaustion (EMFILE), an I/O error already pending on the descriptor (disk full surfaced at close for buffered writers), or the filesystem being unmounted mid-write.

Common situations: Very high fd usage in long-lived wrappers; disk filling during the update (free space ran out between create and close); network filesystems dropping connections during the download-to-temp flow.

Related errors


AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03). Data as JSON: /api/errors/946b02a881544493. Report an issue: GitHub.