puppetlabs/puppet · error · Puppet::Error

Could not read MessagePack data for %{indirection} %{key}: %

Error message

Could not read MessagePack data for %{indirection} %{key}: %{detail}

What it means

Raised by the MessagePack indirection terminus (used for cached catalogs, node, and report data when a msgpack terminus is configured) when the cache file exists but Puppet::FileSystem.read fails with something other than Errno::ENOENT. ENOENT is treated as a cache miss (returns nil), so this error indicates an I/O-level failure such as EACCES (permission denied) or EISDIR (a directory sits where the .msgpack file is expected). The %{detail} component carries the underlying Ruby exception message.

Source

Thrown at lib/puppet/indirector/msgpack.rb:70

      raise ArgumentError, _("invalid key")
    end

    base = Puppet.run_mode.server? ? Puppet[:server_datadir] : Puppet[:client_datadir]
    File.join(base, self.class.indirection_name.to_s, name.to_s + ext)
  end

  private

  def load_msgpack_from_file(file, key)
    msgpack = nil

    begin
      msgpack = Puppet::FileSystem.read(file, :encoding => 'utf-8')
    rescue Errno::ENOENT
      return nil
    rescue => detail
      # TRANSLATORS "MessagePack" is a program name and should not be translated
      raise Puppet::Error, _("Could not read MessagePack data for %{indirection} %{key}: %{detail}") % { indirection: indirection.name, key: key, detail: detail }, detail.backtrace
    end

    begin
      from_msgpack(msgpack)
    rescue => detail
      raise Puppet::Error, _("Could not parse MessagePack data for %{indirection} %{key}: %{detail}") % { indirection: indirection.name, key: key, detail: detail }, detail.backtrace
    end
  end

  def from_msgpack(text)
    model.convert_from('msgpack', text)
  end

  def to_msgpack(object)
    object.render('msgpack')
  end
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Inspect the %{detail} in the message to confirm the errno (EACCES vs EISDIR) and check the exact file path shown in the error
  2. Fix ownership/permissions of the cache tree: chown -R <puppet-user> <vardir> && find <vardir> -type f -exec chmod 644 {} +
  3. Delete the stale cache file (rm <vardir>/<indirection>/<key>.msgpack) so the next find regenerates it from the source of truth
  4. If SELinux is enforcing, run restorecon -Rv on the vardir or check audit.log for denials
  5. Reconsider whether the msgpack terminus is intended; the default cached-catalog format is json, which avoids the msgpack gem dependency entirely

Example fix

# before (agent fails reading root-owned cache file)
sudo puppet agent -t   # creates /var/cache/puppet/catalog/x.msgpack as root:root 0600
# later, puppet service (user puppet) hits:
#   Error: Could not read MessagePack data for catalog mynode: Permission denied

# after: normalize cache ownership and clear stale entries
chown -R puppet:puppet $(puppet config print vardir)
find $(puppet config print vardir) -name '*.msgpack' -delete
systemctl restart puppet
Defensive patterns

Strategy: try-catch

Validate before calling

file = File.join(Puppet[:vardir].to_s, indirection_name, "#{key}.msgpack")
return if Puppet::FileSystem.exist?(file) && !Puppet::FileSystem.readable?(file) ? false : true

Try / catch

begin
  result = Puppet::Resource::Catalog.indirection.find(node)
rescue Puppet::Error => e
  raise unless e.message.start_with?('Could not read MessagePack data')
  Puppet.warning "msgpack cache unreadable, clearing and retrying once: #{e.message}"
  File.delete(cache_path) rescue nil
  result = Puppet::Resource::Catalog.indirection.find(node)
end

Prevention

When it happens

Trigger: Setting cache_terminus = msgpack (or catalog/node/report terminus to msgpack) and calling find/head on the indirection while the file at Puppet[:vardir]/<indirection>/<key>.msgpack is unreadable: owned by root with mode 0600 while puppet runs as a non-root user, an SELinux/AppArmor denial, or a directory created at the exact file path.

Common situations: Agent once ran as root (e.g., manual 'puppet agent -t' via sudo) and later runs as the puppet service user, so cache files are root-owned; vardir migrations or restores that dropped ownership; a stray directory named like the cache file; NFS-mounted vardir with root-squashed permissions.

Related errors


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