ipfs/kubo · error
syncing temp file: %w
Error message
syncing temp file: %w
What it means
`writeBinaryToTempFile` calls `f.Sync()` to guarantee the staged binary bytes reached stable storage before the file is used to replace the live binary. This error wraps a failing fsync; kubo aborts rather than atomically swapping in a binary whose durability is unverified.
Source
Thrown at core/commands/update.go:738
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
}
// extractBinaryFromArchive extracts the kubo/ipfs binary from a tar.gz or zip archive.
func extractBinaryFromArchive(data []byte) ([]byte, error) {
binName := migrations.ExeName("ipfs")
// Try tar.gz first (Unix releases), then zip (Windows releases).
result, tarErr := extractFromTarGz(data, binName)
if tarErr == nil {
return result, nil
}
result, zipErr := extractFromZip(data, binName)View on GitHub (pinned to 329838acdf)
Solutions
- Point TMPDIR at a standard local filesystem: `export TMPDIR=/var/tmp` (ext4/xfs/btrfs) and rerun the update.
- Check `dmesg` for device I/O errors and run fsck if indicated.
- If on a network/FUSE mount by necessity, stage via a local dir first — the update flow always uses the OS temp dir, so TMPDIR is the lever.
- Retry once after a transient failure; the partial file is cleaned up automatically.
Example fix
# before export TMPDIR=/mnt/nfs/tmp ipfs update install v0.30.0 # syncing temp file: ... invalid argument # after export TMPDIR=/var/tmp ipfs update install v0.30.0
Defensive patterns
Strategy: fallback
Validate before calling
// verify fsync works on the temp dir before updating
dir := os.TempDir()
probe, _ := os.CreateTemp(dir, ".fsync-probe-*")
if err := probe.Sync(); err != nil {
// fsync unsupported here: switch TMPDIR to a local FS first
}
probe.Close()
os.Remove(probe.Name()) Type guard
func supportsFsync(dir string) bool {
f, err := os.CreateTemp(dir, ".probe-*")
if err != nil {
return false
}
defer f.Close()
defer os.Remove(f.Name())
return f.Sync() == nil
} Try / catch
path, err := writeBinaryToTempFile(data, ver)
if err != nil {
if strings.Contains(err.Error(), "syncing temp file") {
// fallback: repoint TMPDIR to a local POSIX filesystem and retry
os.Setenv("TMPDIR", "/var/tmp")
return retryUpdate()
}
return err
} Prevention
- Host TMPDIR on ext4/xfs/btrfs, never NFS/SMB/FUSE mounts.
- Test fsync support on any unusual mount before using it for temp files.
- Treat fsync errors as storage-health signals; check dmesg and fsck when they recur.
- Standardize TMPDIR in deployment scripts rather than inheriting the ambient value.
When it happens
Trigger: `ipfs update install` when fsync on the temp executable fails: unsupported filesystem (some FUSE/NFS mounts), pending I/O error on the descriptor, or device-level failure.
Common situations: TMPDIR on NFS/SMB or a FUSE mount that rejects fsync; flaky external drive as TMPDIR; overlayfs quirks in restricted containers; storage hardware failures.
Related errors
- syncing stash file: %w
- closing temp file: %w
- flushing %s: %w
- copying binary to stash: %w
- creating temp file: %w
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/e479e4cec46b723d.
Report an issue: GitHub.