Error message
Could not parse PKey (OpenSSL::PKey::PKeyError)
Also printed as
- OpenSSL::PKey::PKeyError: Could not parse PKey
- Neither PUB key nor PRIV key (OpenSSL::PKey::RSAError)
- invalid curve name (OpenSSL::PKey::ECError)
Uncaught, Ruby prints "…: Could not parse PKey (OpenSSL::PKey::PKeyError)". The class-specific constructors raise `OpenSSL::PKey::RSAError` / `ECError` with their own texts.
Ruby openssl gem — OpenSSL::PKey.read / OpenSSL::PKey::RSA.new / OpenSSL::PKey::EC.new
What it means
`OpenSSL::PKey.read` tried every key format OpenSSL knows (PEM and DER, public and private, encrypted with the given password) and none worked. Ruby does not pass on OpenSSL's specific reason, so the same text covers a mangled PEM, a wrong passphrase and data that is not a key at all. The algorithm-specific constructors fail similarly: `RSA.new` with "Neither PUB key nor PRIV key", `EC.new` with "invalid curve name" (it treats unparseable input as a curve name).
Why it happens
Line breaks replaced by literal \n
commonMulti-line keys in environment variables, Heroku/Render config vars or YAML strings often end up as one line with `\n` sequences.
Encrypted key with a missing or wrong password
common`PKey.read(data)` without the second argument cannot decrypt an encrypted key; a wrong password produces the same error, not a password-specific one.
Not a key OpenSSL can read
occasionalAn OpenSSH public key (`ssh-ed25519 AAAA…`), a JWK JSON document, or a certificate chain file with extra text before the PEM block.
How to fix it
- 1.
Restore newlines and check what you loaded
Convert `\n` sequences back, read the key once at boot, and assert its type and whether it is private.
ruby pem = ENV.fetch("JWT_PUBLIC_KEY").gsub("\\n", "\n") # restore real newlines key = OpenSSL::PKey.read(pem) raise "expected a public EC key" if key.private? || !key.is_a?(OpenSSL::PKey::EC) - 2.
Store multi-line keys where they survive
Rails encrypted credentials or a mounted secret file preserve the PEM exactly, unlike single-line environment variables.
ruby # Rails: keep multi-line keys in encrypted credentials instead of ENV # bin/rails credentials:edit # jwt: # public_key: | # -----BEGIN PUBLIC KEY----- # ... key = OpenSSL::PKey.read(Rails.application.credentials.dig(:jwt, :public_key))