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

LocalTarball#unpack (used when installing from a file: `puppet module install ./pkg.tar.gz`) delegates to Applications::Unpacker.unpack and rescues Puppet::ExecutionFailure, re-raising it as RuntimeError with this message. It fires when the tarball on disk cannot be extracted — malformed archive, wrong compression, or a failing tar environment — mirroring the Unpacker error but on the local-package path.

Source

Thrown at lib/puppet/module_tool/local_tarball.rb:89

        @source.prepare(self)
      end
    end

    private

    # Obtain a suitable temporary path for unpacking tarballs
    #
    # @return [String] path to temporary unpacking location
    # rubocop:disable Naming/MemoizedInstanceVariableName
    def tmpdir
      @dir ||= Dir.mktmpdir('local-tarball', Puppet::Forge::Cache.base_path)
    end
    # rubocop:enable Naming/MemoizedInstanceVariableName

    def unpack(file, destination)
      Puppet::ModuleTool::Applications::Unpacker.unpack(file, destination)
    rescue Puppet::ExecutionFailure => e
      raise RuntimeError, _("Could not extract contents of module archive: %{message}") % { message: e.message }
    end
  end
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Validate the archive first: `tar -tzf my-module.tar.gz` must list a single root directory containing metadata.json
  2. Rebuild with the supported tool: `puppet module build` in the module directory, then install the fresh pkg/*.tar.gz
  3. If the file came from CI, fix the packaging step (gzip the tar, keep the module-name/ root dir) instead of renaming other formats
  4. Check disk space and TMPDIR, then retry after clearing the module working dir

Example fix

# before
$ puppet module install ./my-module.tar.gz
# Error: Could not extract contents of module archive: tar: Archive is compressed with unknown method

# after
$ cd my-module && puppet module build
$ puppet module install ./pkg/my-module-0.1.0.tar.gz
Defensive patterns

Strategy: try-catch

Validate before calling

def valid_module_tarball?(path)
  return false unless File.exist?(path) && File.size(path) > 0
  entries = `tar -tzf #{Shellwords.escape(path)}`.split("\n")
  entries.any? { |e| e.end_with?('metadata.json') }
rescue Errno::ENOENT
  false
end

abort 'not a puppet module tarball (no metadata.json)' unless valid_module_tarball?(pkg)

Try / catch

begin
  Puppet::ModuleTool::LocalTarball.new(pkg_path).unpack(pkg_path, dest)
rescue RuntimeError => e
  raise "local tarball #{pkg_path} failed to extract: #{e.message} — rebuild with `puppet module build`"
end

Prevention

When it happens

Trigger: Running `puppet module install ./my-module.tar.gz` where the file is not a valid gzipped tar produced by `puppet module build` — e.g. a plain directory tarballed without gzip, a zip renamed to .tar.gz, or a truncated file.

Common situations: Building tarballs with custom scripts that skip the metadata.json root layout; CI artifacts zipped then renamed; transferring modules through tools that mangle compression; empty 0-byte artifacts from a failed build job.

Related errors


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