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

  1. Point TMPDIR at a POSIX filesystem that honors exec bits: `export TMPDIR=/var/tmp` and rerun.
  2. If on exFAT/vfat, remount with proper options (e.g. `fmask=022`) or move to ext4/xfs.
  3. Check MAC-policy denials: `sudo ausearch -m avc -ts recent` for SELinux; adjust policy or use `setenforce 0` temporarily to confirm.
  4. 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

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


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