ipfs/kubo · error
refusing to export key to %s: not a regular file, character
Error message
refusing to export key to %s: not a regular file, character device or pipe
What it means
writeExportedKey only writes exported private keys to three kinds of targets: regular files (atomically, via temp file + rename), character devices, and named pipes (written in place). If the output path exists but is something else — a directory, a unix socket, a block device, etc. — the export is refused rather than failing obscurely later. This is a deliberate safety refusal: keys must not be 'written' into targets that cannot hold them.
Source
Thrown at core/commands/keystore.go:355
return err
}
default:
return fmt.Errorf("unrecognized export format: %s", exportFormat)
}
return nil
}
// Stat resolves symlinks: -o /dev/stdout is a link into /proc/self/fd.
info, err := os.Stat(outPath)
if err != nil && !errors.Is(err, os.ErrNotExist) {
return err
}
if err == nil {
if info.Mode()&inPlaceModes != 0 {
return writeExportedKeyInPlace(outPath, writeKey)
}
if !info.Mode().IsRegular() {
return fmt.Errorf("refusing to export key to %s: not a regular file, character device or pipe", outPath)
}
}
// 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 theView on GitHub (pinned to 329838acdf)
Solutions
- Pass a path to a regular file (existing or not), not a directory or socket
- If targeting a directory, append the intended filename: `-o /dir/mykey.pem`
- Check what is at the path: `ls -la <path>` / `stat <path>` and remove or rename the non-regular object
- If you wanted stdout, omit `-o` or use a pipe/character device like /dev/stdout
Example fix
// before ipfs key export mykey -o /tmp/keys # directory // after ipfs key export mykey -o /tmp/keys/mykey.pem
Defensive patterns
Strategy: validation
Validate before calling
import os
mode = os.lstat(out_path).st_mode
if not (stat.S_ISREG(mode) or stat.S_ISCHR(mode) or stat.S_ISFIFO(mode)):
raise ValueError(f"refusing export target {out_path}: not a regular file, char device or pipe") Prevention
- Always pass a full file path (including filename) to -o, never a directory
- Run `stat <path>` before exporting to an existing path
- Reserve dedicated directories for key exports to avoid stray sockets/special files
When it happens
Trigger: `ipfs key export <name> -o /some/existing/directory`; `-o /path/to/unix.sock`; `-o` pointing at a block device or other special file. os.Stat succeeded and the mode did not match regular/char-device/pipe.
Common situations: Forgetting the output filename and passing a directory; a stale socket file at the target path; shell variable expanding empty so `-o` gets a wrong value; mount points or special files on /dev.
Related errors
- creating temporary file for %s: %w
- flushing %s: %w
- writing %s: %w
- too many levels of symbolic links: %s
- refusing to export key to %s: it changed type while being op
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/b157df919b3860c5.
Report an issue: GitHub.