Skip to content
ecdsa.com
Ruby openssl gemRuby

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

How to fix it

  1. 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. 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))

Related errors

Browse the full signature error database