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
- Free disk space on the temp filesystem and retry: `df -h "$TMPDIR"`.
- Check for fd leaks/limits: `ulimit -n`, `ls /proc/self/fd | wc -l`; raise the soft limit if near it.
- Inspect `dmesg` for underlying storage errors on the temp filesystem.
- 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
- Run updates from a clean environment without hundreds of open file descriptors.
- Keep a healthy fd limit (>= 1024) for the process running the update.
- Watch for EIO trends via dmesg and replace failing storage proactively.
- Retry once after transient failures — partial temp files are cleaned up automatically.
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
- syncing temp file: %w
- copying binary to stash: %w
- syncing stash file: %w
- creating temp file: %w
- writing temp file: %w
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/946b02a881544493.
Report an issue: GitHub.