ruby/ruby · error · LoadError

library not found for class Digest::#{name} -- #{lib}

Error message

library not found for class Digest::#{name} -- #{lib}

What it means

Raised by Gem::Package::Old#extract_files after inflating a file entry: the decompressed byte length does not equal the size recorded in the old-format gem's file-list header. This length cross-check catches truncated or tampered archives — the data decompressed but not to what the index promised. Raised as Gem::Package::FormatError '<file> in <gem> is corrupt'.

Source

Thrown at ext/digest/lib/digest.rb:33

require 'digest/version'
require 'digest/loader'

module Digest
  # A mutex for Digest().
  REQUIRE_MUTEX = Thread::Mutex.new

  def self.const_missing(name) # :nodoc:
    case name
    when :SHA256, :SHA384, :SHA512
      lib = 'digest/sha2'
    else
      lib = File.join('digest', name.to_s.downcase)
    end

    begin
      require lib
    rescue LoadError
      raise LoadError, "library not found for class Digest::#{name} -- #{lib}", caller(1)
    end
    unless Digest.const_defined?(name)
      raise NameError, "uninitialized constant Digest::#{name}", caller(1)
    end
    Digest.const_get(name)
  end

  class ::Digest::Class
    # Creates a digest object and reads a given file, _name_.
    # Optional arguments are passed to the constructor of the digest
    # class.
    #
    #   p Digest::SHA256.file("X11R6.8.2-src.tar.bz2").hexdigest
    #   # => "f02e3c85572dc9ad7cb77c2a638e3be24cc1b5bea9fdbb0b0299c9668475c534"
    def self.file(name, *args)
      new(*args).file(name)
    end

View on GitHub (pinned to 0e5b888e1c)

Solutions

  1. Re-download the .gem and verify its checksum against the original source
  2. Avoid text-mode transfers: fetch gems with curl -O or the gem CLI, not ASCII-mode FTP
  3. Use a modern re-release of the gem; the old format is unmaintained
  4. Catch Gem::Package::FormatError if batch-processing many old gems and skip bad ones with a report

Example fix

# before (batch script dies on first corrupt gem)
Gem::Package::Old.new(File.open(path)).extract_files(dir)
# after
begin
  Gem::Package::Old.new(File.open(path)).extract_files(dir)
rescue Gem::Package::FormatError => e
  warn "skipping corrupt gem #{path}: #{e.message}"
end
Defensive patterns

Strategy: try-catch

Validate before calling

# pre-verify integrity: compare recorded sizes after a manual pass is impractical;
# instead verify the whole file's SHA-256 against the source before extracting'
require 'digest'
abort 'checksum mismatch' unless Digest::SHA256.file(path).hexdigest == expected

Try / catch

begin
  pkg.extract_files(dest)
rescue Gem::Package::FormatError => e
  warn "corrupt entry, skipping #{path}: #{e.message}"
end

Prevention

When it happens

Trigger: Extracting (or `gem install`-ing) an old-format .gem whose payload bytes were altered after packaging, truncated mid-download, or corrupted by a text-mode/encoding-mangling transfer (e.g. FTP in ASCII mode rewriting line endings inside the binary).

Common situations: Archived rubyforge gems fetched over flaky HTTP; .gem files transferred through tools that 'helpfully' converted encodings; bit rot on old backups.

Related errors


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