ipfs/kubo · error
flushing %s: %w
Error message
flushing %s: %w
What it means
After writing the exported key into the temp file, writeExportedKey calls file.Sync() to flush it to stable storage before the atomic rename, so a crash can never leave an empty or truncated key file. This error joins the fsync failure with the temp file's Abort. It indicates an I/O-layer problem persisting the data, not a key-format problem.
Source
Thrown at core/commands/keystore.go:376
// The key is written next to the target and renamed over it, so replace
// what a symlink points at rather than the symlink itself.
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
}View on GitHub (pinned to 329838acdf)
Solutions
- Check the wrapped errno: EIO usually means failing hardware — run fsck or replace the disk
- Retry the export to a different filesystem (e.g. local disk instead of a network mount)
- The temp file was aborted, so no partial file remains — re-run once hardware/fs is healthy
- Avoid exporting directly onto fuse/network filesystems known to reject fsync
Example fix
// before ipfs key export mykey -o /mnt/flaky-nfs/mykey.pem // after ipfs key export mykey -o /root/mykey.pem && cp /root/mykey.pem /mnt/flaky-nfs/
Defensive patterns
Strategy: retry
Validate before calling
// Prefer local, fsync-capable filesystems for key export mount | grep "$(df --output=target "$(dirname "$out")" | tail -1)" # avoid nfs/fuse targets
Try / catch
if err := writeExportedKey(outPath, r, fmt); err != nil && strings.Contains(err.Error(), "flushing") {
// transient fsync failure: retry once on a local filesystem
return retryExport(outPath, r, fmt)
} Prevention
- Export keys to local disk first, then transfer
- Watch SMART/dmesg for disk errors after this error
- Avoid fuse/network filesystems with known fsync issues for sensitive writes
When it happens
Trigger: `ipfs key export` to a filesystem whose fsync fails: disk errors, some network filesystems (NFS oddities), full journal, or exporting onto virtual filesystems that do not support fsync (certain fuse mounts, /proc-like fs).
Common situations: Exporting to a flaky USB drive or failing disk; fuse/network mounts with unreliable fsync; container storage drivers with fsync quirks.
Related errors
- encoding PEM block: %w
- refusing to export key to %s: not a regular file, character
- creating temporary file for %s: %w
- writing %s: %w
- too many levels of symbolic links: %s
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/f8b28b4fa7804db3.
Report an issue: GitHub.