ipfs/kubo · error

writing %s: %w

Error message

writing %s: %w

What it means

After a successful Sync, the temp file is closed and, inside atomicfile, renamed over the target. This error wraps a failure from file.Close(), which for atomicfile includes the rename operation. The export therefore did not complete: either the flush/close syscall failed or the rename could not replace the target (e.g. it cannot be renamed over).

Source

Thrown at core/commands/keystore.go:379

	outPath, err = resolveSymlink(outPath)
	if err != nil {
		return err
	}

	file, err := atomicfile.New(outPath, exportedKeyFileMode)
	if err != nil {
		return fmt.Errorf("creating temporary file for %s: %w", outPath, err)
	}
	if err := writeKey(file); err != nil {
		return errors.Join(err, file.Abort())
	}
	// Flush before the rename, so a crash cannot leave an empty file where the
	// previous export was.
	if err := file.Sync(); err != nil {
		return errors.Join(fmt.Errorf("flushing %s: %w", outPath, err), file.Abort())
	}
	if err := file.Close(); err != nil {
		return fmt.Errorf("writing %s: %w", outPath, err)
	}
	return nil
}

// resolveSymlink returns the path a chain of symlinks ends at.
// filepath.EvalSymlinks cannot be used on the path as a whole: it fails when
// the last link points at a file that does not exist yet, and such a link
// still says where the key belongs. A path that cannot be inspected is
// returned unchanged, so that the caller's write reports the problem.
func resolveSymlink(path string) (string, error) {
	for range maxSymlinkHops {
		info, err := os.Lstat(path)
		if err != nil || info.Mode()&os.ModeSymlink == 0 {
			return path, nil
		}
		target, err := os.Readlink(path)
		if err != nil {
			return "", err

View on GitHub (pinned to 329838acdf)

Solutions

  1. Check the wrapped errno: EBUSY/EXDEV/EPERM indicate the target cannot be renamed over — export to a different path
  2. If the target is a bind mount, write to a new file and remount/copy instead
  3. Verify you own the parent directory or have write+execute on it
  4. Retry after removing anything special about the target path (mount point, immutable flag: chattr -i)

Example fix

// before
ipfs key export mykey -o /etc/config/identity.key   # bind-mounted
// after
ipfs key export mykey -o /tmp/identity.key && cp /tmp/identity.key /etc/config/identity.key
Defensive patterns

Strategy: validation

Validate before calling

# ensure target is not a mount point / bind mount and parent is writable
mountpoint -q "$out" && echo 'cannot rename over mount point'
findmnt -T "$out"

Prevention

When it happens

Trigger: `ipfs key export -o <path>` where the target is a bind-mounted file, a mount point, or the parent directory disallows rename (sticky-bit/dir permission issues, cross-device conditions). Also close-time write-back errors on failing storage.

Common situations: Trying to overwrite a file that is a bind mount inside a container; exporting over a file in a directory with the sticky bit not owned by the user; overlayfs/docker volume edge cases where rename over the target fails.

Related errors


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