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

  1. Check the wrapped error (%w) for the real write failure: ENOSPC means free disk space, EPIPE means the downstream consumer exited
  2. If piping, ensure the consumer reads all output before exiting (avoid `head` truncation)
  3. Retry the export to a different, healthy destination path
  4. 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

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


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