ipfs/kubo · error
chmod temp file: %w
Error message
chmod temp file: %w
What it means
After writing and syncing the staged binary, `writeBinaryToTempFile` calls `f.Chmod(0o755)` so the temp file is executable before replacing the installed kubo binary. This error wraps a chmod failure; without the execute bit the staged file is unusable as a binary, so the update aborts.
Source
Thrown at core/commands/update.go:741
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)
if zipErr == nil {
return result, nil
}View on GitHub (pinned to 329838acdf)
Solutions
- Point TMPDIR at a POSIX filesystem that honors exec bits: `export TMPDIR=/var/tmp` and rerun.
- If on exFAT/vfat, remount with proper options (e.g. `fmask=022`) or move to ext4/xfs.
- Check MAC-policy denials: `sudo ausearch -m avc -ts recent` for SELinux; adjust policy or use `setenforce 0` temporarily to confirm.
- Retry after fixing; the aborted temp file is removed automatically.
Example fix
# before export TMPDIR=/mnt/usbstick # exFAT: chmod not supported ipfs update install v0.30.0 # chmod temp file: operation not permitted # after export TMPDIR=/var/tmp # ext4 honors 0755 ipfs update install v0.30.0
Defensive patterns
Strategy: validation
Validate before calling
// verify the temp dir supports exec bits before updating
probe, _ := os.CreateTemp(os.TempDir(), ".chmod-probe-*")
if err := probe.Chmod(0o755); err != nil {
// chmod unsupported (vfat/exFAT or MAC policy): repoint TMPDIR first
}
probe.Close()
os.Remove(probe.Name()) Type guard
func supportsExecBits(dir string) bool {
f, err := os.CreateTemp(dir, ".probe-*")
if err != nil {
return false
}
defer f.Close()
defer os.Remove(f.Name())
if f.Chmod(0o755) != nil {
return false
}
fi, _ := os.Stat(f.Name())
return fi.Mode().Perm() == 0o755
} Try / catch
path, err := writeBinaryToTempFile(data, ver)
if err != nil {
if strings.Contains(err.Error(), "chmod temp file") {
// fallback: use a POSIX FS for temp, or remount with fmask=022
os.Setenv("TMPDIR", "/var/tmp")
return retryUpdate()
}
return err
} Prevention
- Never point TMPDIR at vfat/exFAT/ntfs-3g mounts for binary staging.
- Check SELinux/AppArmor AVC denials if permissions look correct but chmod fails.
- Verify the staged file's mode (0755) on any custom update tooling.
- Use distribution-standard temp directories (/tmp, /var/tmp) in automation.
When it happens
Trigger: `ipfs update install` when chmod fails on the temp file: the filesystem does not support permission changes (some FAT/exFAT mounts, certain network filesystems), or an ACL/MAC policy (SELinux) denies the change.
Common situations: TMPDIR on a USB stick or Windows-formatted (vfat/exFAT/ntfs-3g) mount that mangles exec bits; restrictive umask/ACLs on the temp dir; SELinux denials in enforcing mode.
Related errors
- reading stash directory: %w
- creating temp file: %w
- serveHTTPApi: SetAPIAddr() failed: %w
- %s is not writeable by the current user
- cannot write to %s, incorrect permissions
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/df50b894ae342562.
Report an issue: GitHub.