ipfs/kubo · error
unable to unmarshall format=%s: %w
Error message
unable to unmarshall format=%s: %w
What it means
The input was not a PEM block, but crypto.UnmarshalPrivateKey (libp2p protobuf-cleartext format) failed to decode the bytes as a valid libp2p private key. The wrapped error carries the underlying protobuf/unmarshal reason.
Source
Thrown at core/commands/keystore.go:521
// In case ed25519.PrivateKey is returned we need the pointer for
// conversion to libp2p (see export command for more details).
if ed25519KeyPointer, ok := stdKey.(ed25519.PrivateKey); ok {
stdKey = &ed25519KeyPointer
}
sk, _, err = crypto.KeyPairFromStdKey(stdKey)
if err != nil {
return fmt.Errorf("converting std Go key to libp2p key: %w", err)
}
case keyFormatLibp2pCleartextOption:
sk, err = crypto.UnmarshalPrivateKey(data)
if err != nil {
// check if data is PEM, if so, provide user with hint
pemBlock, _ := pem.Decode(data)
if pemBlock != nil {
return fmt.Errorf("unexpected PEM block for format=%s: try again with format=%s", keyFormatLibp2pCleartextOption, keyFormatPemCleartextOption)
}
return fmt.Errorf("unable to unmarshall format=%s: %w", keyFormatLibp2pCleartextOption, err)
}
default:
return fmt.Errorf("unrecognized import format: %s", importFormat)
}
// We only allow importing keys of the same type we generate (see list in
// https://github.com/ipfs/interface-go-ipfs-core/blob/1c3d8fc/options/key.go#L58-L60),
// unless explicitly stated by the user.
allowAnyKeyType, _ := req.Options[keyAllowAnyTypeOptionName].(bool)
if !allowAnyKeyType {
switch t := sk.(type) {
case *crypto.RsaPrivateKey, *crypto.Ed25519PrivateKey, *crypto.Secp256k1PrivateKey:
default:
return fmt.Errorf("key type %T is not allowed to be imported, only RSA, Ed25519, or Secp256k1;"+
" use flag --%s if you are sure of what you're doing",
t, keyAllowAnyTypeOptionName)
}View on GitHub (pinned to 329838acdf)
Solutions
- Confirm the file's origin and format: `file keyfile` and compare with how it was exported (`ipfs key export --format=...`)
- Re-export the key from the source node and retry the import
- If it is a PEM key, use `-f pem-pkcs8-cleartext` (note error 343 covers the detectable PEM case)
- Check file size/integrity; re-copy if the transfer may have truncated it
Example fix
// before: format mismatch between export and import $ ipfs key export mykey -f pem-pkcs8-cleartext > k.pem && ipfs key import mykey k.pem Error: unable to unmarshall format=libp2p-protobuf-cleartext: ... // after: match formats $ ipfs key import mykey -f pem-pkcs8-cleartext k.pem
Defensive patterns
Strategy: validation
Validate before calling
info, _ := os.Stat(keyFile)
if info.Size() == 0 || info.Size() < 16 {
return fmt.Errorf("key file %s looks truncated or empty", keyFile)
}
// also verify it is not PEM (that needs -f pem-pkcs8-cleartext) Try / catch
if err := importKey(); err != nil {
if strings.Contains(err.Error(), "unable to unmarshall") {
// wrong format or corrupt file: re-export from source node
}
} Prevention
- Export and import with the same `--format` value
- Check file integrity after copying (size, sha256sum)
- Do not import public keys or certificates with key import
When it happens
Trigger: `ipfs key import name keyfile` (default format) where keyfile is garbage, a corrupted export from `ipfs key export`, a raw openssl/PEM-ish file that pem.Decode also rejects, or a truncated protobuf key.
Common situations: Importing a file exported with a different `--format` than used at import time, binary corruption during transfer, or accidentally importing a public key or certificate.
Related errors
- converting std Go key to libp2p key: %w
- expected PRIVATE KEY type in PEM block but got: %s
- parsing PKCS8 format: %w
- unexpected PEM block for format=%s: try again with format=%s
- unrecognized import format: %s
AI-assisted analysis of ipfs/kubo@329838acdf (2026-09-03).
Data as JSON: /api/errors/d9897a6eabb803a9.
Report an issue: GitHub.