ruby/ruby · error · Gem::Security::Exception

incorrect signing key for re-signing #{expired_certificate.s

Error message

incorrect signing key for re-signing #{expired_certificate.subject}

What it means

Gem::Security.re_sign (reached automatically from Gem::Security::Signer#sign when your signing certificate expires during gem build) first calls expired_certificate.check_private_key(private_key); if the private key does not match the certificate's public key it refuses to re-sign. The message names the certificate subject so you can tell which pair is mismatched.

Source

Thrown at lib/rubygems/security.rb:509

    cn, dcs = email_address.split "@"

    dcs = dcs.split "."

    OpenSSL::X509::Name.new([
      ["CN", cn],
      *dcs.map {|dc| ["DC", dc] },
    ])
  end

  ##
  # Signs +expired_certificate+ with +private_key+ if the keys match and the
  # expired certificate was self-signed.
  #--
  # TODO increment serial

  def self.re_sign(expired_certificate, private_key, age = ONE_YEAR, extensions = EXTENSIONS)
    raise Gem::Security::Exception,
          "incorrect signing key for re-signing " +
          expired_certificate.subject.to_s unless
      expired_certificate.check_private_key(private_key)

    unless expired_certificate.subject.to_s ==
           expired_certificate.issuer.to_s
      subject = alt_name_or_x509_entry expired_certificate, :subject
      issuer  = alt_name_or_x509_entry expired_certificate, :issuer

      raise Gem::Security::Exception,
            "#{subject} is not self-signed, contact #{issuer} " \
            "to obtain a valid certificate"
    end

    serial = expired_certificate.serial + 1

    create_cert_self_signed(expired_certificate.subject, private_key, age,
                            extensions, serial)

View on GitHub (pinned to 0e5b888e1c)

Solutions

  1. Rebuild a matching pair and reinstall the cert: gem cert --build you@example.com, then gem cert --add gem-public_cert.pem, keeping gem-private_key.pem and gem-public_cert.pem together
  2. Before building, verify pairing yourself: OpenSSL::X509::Certificate.new(File.read(cert)).check_private_key(OpenSSL::PKey.read(File.read(key)))
  3. Set :expiration_length_days in ~/.gemrc so certs are re-signed automatically while the correct key is still configured

Example fix

# before: expired cert + wrong key on disk
$ gem build mygem.gemspec
#=> incorrect signing key for re-signing /CN=me/DC=example/DC=com

# after: rebuild the pair together
$ gem cert --build me@example.com
$ gem cert --add gem-public_cert.pem
$ gem build mygem.gemspec
Defensive patterns

Strategy: validation

Validate before calling

cert = OpenSSL::X509::Certificate.new(File.read(cert_path))
key  = OpenSSL::PKey.read(File.read(key_path))
raise "key does not match #{cert.subject}" unless cert.check_private_key(key)
warn "cert expires #{cert.not_after} — rebuild the pair soon" if cert.not_after < Time.now + 30*24*3600

Prevention

When it happens

Trigger: gem build with an expired ~/.gem/gem-public_cert.pem while gem-private_key.pem belongs to a different key pair; regenerating the key (or cert) at a different time so the two files no longer match; copying only one half of a pair between machines.

Common situations: Multi-machine or CI signing where the key and cert were sourced separately; recovering after cert expiry with a newly built key; stale certs left in place while the key was rebuilt via gem cert --build.

Understand the failure class

Related errors


AI-assisted analysis of ruby/ruby@0e5b888e1c (2026-08-21). Data as JSON: /api/errors/879c7150306c06e1. Report an issue: GitHub.