puppetlabs/puppet · error · RuntimeError

Could not extract contents of module archive: %{message}

Error message

Could not extract contents of module archive: %{message}

What it means

Unpacker#unpack extracts a downloaded module tarball by delegating to Puppet::ModuleTool::Tar.instance.unpack (a tar shell-out). If the underlying command fails, the Puppet::ExecutionFailure is re-raised as a plain RuntimeError with the command's error text appended. It almost always means the archive on disk is not a readable gzipped tar or the extraction environment is broken, not that Puppet logic failed.

Source

Thrown at lib/puppet/module_tool/applications/unpacker.rb:59

        module_dir
      end

      # @api private
      # Error on symlinks and other junk
      def sanity_check
        symlinks = Dir.glob("#{tmpdir}/**/*", File::FNM_DOTMATCH).map { |f| Pathname.new(f) }.select { |p| Puppet::FileSystem.symlink? p }
        tmpdirpath = Pathname.new tmpdir

        symlinks.each do |s|
          Puppet.warning _("Symlinks in modules are unsupported. Please investigate symlink %{from}->%{to}.") % { from: s.relative_path_from(tmpdirpath), to: Puppet::FileSystem.readlink(s) }
        end
      end

      # @api private
      def unpack
        Puppet::ModuleTool::Tar.instance.unpack(@filename.to_s, tmpdir, [@module_path.stat.uid, @module_path.stat.gid].join(':'))
      rescue Puppet::ExecutionFailure => e
        raise RuntimeError, _("Could not extract contents of module archive: %{message}") % { message: e.message }
      end

      # @api private
      def root_dir
        return @root_dir if @root_dir

        # Grab the first directory containing a metadata.json file
        metadata_file = Dir["#{tmpdir}/**/metadata.json"].min_by(&:length)

        if metadata_file
          @root_dir = Pathname.new(metadata_file).dirname
        else
          raise _("No valid metadata.json found!")
        end
      end

      # @api private
      def module_name

View on GitHub (pinned to e227c27540)

Solutions

  1. Clear the Forge cache (delete the tarball under Puppet::Forge::Cache.base_path, ~/.puppet/cache or /opt/puppetlabs/puppet/cache) and retry the install
  2. Verify the file is a valid gzipped tar before retrying: `tar -tzf <file>.tar.gz | head` (also `file <file>.tar.gz`)
  3. Check disk space and writability of the temporary directory (df -h, echo $TMPDIR)
  4. On Windows, ensure the bundled tar/gzip tooling that ships with Puppet is available on PATH, or install via a Puppet-provided package

Example fix

# before
$ puppet module install puppetlabs-stdlib
# Error: Could not extract contents of module archive: tar: This does not look like a tar archive

# after
$ rm -rf "$(puppet config print module_working_dir)"/*
$ puppet module install puppetlabs-stdlib
Defensive patterns

Strategy: try-catch

Validate before calling

def extractable?(tarball)
  File.exist?(tarball) && File.size(tarball) > 0 &&
    system('tar', '-tzf', tarball, out: File::NULL, err: File::NULL)
end

abort 'archive is not a readable gzipped tar' unless extractable?(archive)

Try / catch

begin
  Puppet::ModuleTool::Applications::Unpacker.run(archive_file, destination)
rescue RuntimeError => e
  raise "module archive unpack failed for #{archive_file}: #{e.message}" unless e.message =~ /Could not extract/
  Puppet::Forge::Cache.clean
  retry once_after_redownload
end

Prevention

When it happens

Trigger: Calling Puppet::ModuleTool::Applications::Unpacker.run/archive extraction for a file that tar cannot process: a truncated download, an HTML proxy error page saved with a .tar.gz name, a non-gzip archive, or a system where the tar binary is missing/fails (disk full in the tmpdir).

Common situations: Interrupted `puppet module install` leaving a partial file in the Forge cache; corporate proxies or captive portals mangling downloads; Windows boxes without the module-tool tar shim; TMPDIR on a full filesystem; double-compressed or wrongly-packaged tarballs from a private Forge.

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/4e2a44fc2bbf1664. Report an issue: GitHub.