{"record":{"id":"4b60008371a6238d","repo":"puppetlabs/puppet","slug":"downloaded-release-for-name-did-not-match-expec","errorCode":null,"errorMessage":"Downloaded release for %{name} did not match expected checksum %{checksum}","messagePattern":"Downloaded release for %(.+?) did not match expected checksum %(.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"lib/puppet/forge.rb","lineNumber":221,"sourceCode":"      @file ||= Tempfile.new(name, Puppet::Forge::Cache.base_path).tap(&:binmode)\n    end\n    # rubocop:enable Naming/MemoizedInstanceVariableName\n\n    def download(uri, destination)\n      response = @source.make_http_request(uri, destination)\n      destination.flush and destination.close\n      unless response.code == 200\n        raise Puppet::Forge::Errors::ResponseError.new(:uri => response.url, :response => response)\n      end\n    end\n\n    def validate_checksum(file, checksum, digest_class)\n      if Puppet.runtime[:facter].value(:fips_enabled) && digest_class == Digest::MD5\n        raise _(\"Module install using MD5 is prohibited in FIPS mode.\")\n      end\n\n      if digest_class.file(file.path).hexdigest != checksum\n        raise RuntimeError, _(\"Downloaded release for %{name} did not match expected checksum %{checksum}\") % { name: name, checksum: checksum }\n      end\n    end\n\n    def unpack(file, destination)\n      Puppet::ModuleTool::Applications::Unpacker.unpack(file.path, destination)\n    rescue Puppet::ExecutionFailure => e\n      raise RuntimeError, _(\"Could not extract contents of module archive: %{message}\") % { message: e.message }\n    end\n\n    def deprecated?\n      @data['module'] && !@data['module']['deprecated_at'].nil?\n    end\n  end\n\n  private\n\n  def process(list)\n    l = list.map do |release|","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/forge.rb#L203-L239","documentation":"Puppet raises this RuntimeError in Puppet::Forge::Release#validate_checksum after a module release tarball is downloaded from the Forge. The hex digest computed over the downloaded file does not equal the checksum string that the Forge metadata published for that release. It means the bytes you received are not the bytes the Forge published: corruption in transit, a truncating proxy or cache, or a tampered artifact.","triggerScenarios":"A 'puppet module install' (or Puppet::Forge API use: release.download then validate_checksum) where digest_class.file(file.path).hexdigest != checksum. Typical producers: an SSL-inspecting proxy returns a truncated body or an HTML error page as the tarball; a mirror or Artifactory cache serves mixed bytes; the temp file write fails part way (disk full) so the digest runs over a partial file.","commonSituations":"Corporate proxies and TLS-inspection appliances that alter download bodies; stale or corrupted artifacts in a module mirror; a full /tmp or module_working_dir that truncates the write; flaky networks that drop the body mid-stream without closing with an error.","solutions":["Retry the install. Transient corruption is the most common cause, and a retry fetches a fresh tarball.","Download the tarball by hand (curl -sSL <release_url> | sha256sum) and compare with the checksum on the Forge release page. If they differ, the corruption is between you and the Forge: clear proxy and mirror caches, then retry.","Check free space on the temp filesystem (df -h /tmp and puppet config print module_working_dir). ENOSPC during destination.flush/close produces a truncated file and this exact mismatch.","If the manual download matches the Forge checksum but the install still fails, purge Puppet's own module cache directory and retry.","On very old Puppet versions in FIPS mode, note that the MD5 path is rejected outright; upgrade Puppet so the release uses SHA-256."],"exampleFix":"# before: corrupted cached tarball keeps failing every run\npuppet module install puppetlabs-stdlib --version 9.0.0\n# -> Downloaded release for puppetlabs-stdlib did not match expected checksum ...\n\n# after: purge the partial download so the tarball is fetched fresh, then retry\nrm -rf \"$(puppet config print module_working_dir)\"/*\npuppet module install puppetlabs-stdlib --version 9.0.0","handlingStrategy":"retry","validationCode":"# Before programmatic installs: give the download a clean, roomy target\nrequire 'fileutils'\nFileUtils.rm_rf(Puppet[:module_working_dir]) if Puppet[:module_working_dir]\nabort 'not enough disk for module install' if `df -Pk /tmp`.split[3].to_i < 50_000","typeGuard":null,"tryCatchPattern":"attempts = 0\nbegin\n  Puppet::ModuleTool::Applications::Installer.run('puppetlabs-stdlib', modulepath: mp)\nrescue RuntimeError => e\n  raise unless e.message =~ /did not match expected checksum/\n  FileUtils.rm_rf(Puppet[:module_working_dir])  # purge the corrupted tarball\n  retry if (attempts += 1) < 3\n  raise\nend","preventionTips":["Purge the module working dir before scripted installs so partial tarballs never persist.","Bypass or fix SSL-inspecting proxies for forgeapi.puppet.com downloads.","Keep mirrors (Artifactory/Nexus) healthy and pinned to verified checksums.","Pin module versions in a Puppetfile so re-downloads are rare and reproducible."],"tags":["puppet","forge","module-install","checksum","download-corruption"],"backgroundTag":"checksum-verification-failed","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}