ipfs/kubo · error
encoding PEM block: %w
Error message
encoding PEM block: %w
What it means
`ipfs key export --format=pem-pkcs8-cleartext` marshals the private key to PKCS8 bytes and then encodes them as a PEM block written to the output writer. encoding/pem.Encode only fails when the underlying writer returns an error, so this wraps an I/O failure that happened while writing the PEM text to the destination (file, stdout, or character device). It is not a key-format problem; the key bytes were already produced successfully.
Source
Thrown at core/commands/keystore.go:333
// followed and the key lands where they point.
//
// A path that resolves to a character device or a pipe cannot be renamed over
// and is written in place, without permission enforcement, because the
// operating system owns those objects. Every other target is refused.
func writeExportedKey(outPath string, outReader io.Reader, exportFormat string) error {
writeKey := func(w io.Writer) error {
switch exportFormat {
case keyFormatPemCleartextOption:
privKeyBytes, err := io.ReadAll(outReader)
if err != nil {
return err
}
if err := pem.Encode(w, &pem.Block{
Type: "PRIVATE KEY",
Bytes: privKeyBytes,
}); err != nil {
return fmt.Errorf("encoding PEM block: %w", err)
}
case keyFormatLibp2pCleartextOption:
if _, err := io.Copy(w, outReader); err != nil {
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 {View on GitHub (pinned to 329838acdf)
Solutions
- Check the wrapped error (%w) for the real write failure: ENOSPC means free disk space, EPIPE means the downstream consumer exited
- If piping, ensure the consumer reads all output before exiting (avoid `head` truncation)
- Retry the export to a different, healthy destination path
- Verify write permissions and disk state on the output filesystem
Example fix
// before ipfs key export mykey --format=pem-pkcs8-cleartext | head -c 100 # EPIPE // after ipfs key export mykey --format=pem-pkcs8-cleartext -o mykey.pem # write to file
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check destination writability and space df -h "$(dirname "$out")" && test -w "$(dirname "$out")" && echo writable
Try / catch
// In Go callers wrapping the CLI output handling:
if err := writeExportedKey(outPath, r, exportFormat); err != nil {
var pe *fs.PathError
if errors.As(err, &pe) {
log.Printf("write to %s failed: %v", pe.Path, pe.Err)
}
return err
} Prevention
- Write exports to regular files rather than pipes with early-exiting consumers
- Monitor disk space/quota on the export target filesystem
- Avoid exporting onto flaky removable or network storage
When it happens
Trigger: Running `ipfs key export <name> --format=pem-pkcs8-cleartext -o <path>` (or letting output go through PostRun's writeExportedKey) where the write target returns an error mid-write: full disk, closed pipe (e.g. `ipfs key export k | head -c 1`), EIO on a failing device, or a character device that rejects writes.
Common situations: Piping output into a consumer that closes the pipe early; exporting to a removable drive that disconnects; disk quota/full-disk conditions; broken /dev/stdout redirection in restricted containers.
Related errors
- flushing %s: %w
- PEM block not found in input data: %s
- failed to read key: %w
- refusing to export key to %s: not a regular file, character
- creating temporary file for %s: %w
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/f126c217e187f7bc.
Report an issue: GitHub.