{"record":{"id":"1cc60d27336fce8f","repo":"puppetlabs/puppet","slug":"could-not-read-messagepack-data-for-indirection","errorCode":null,"errorMessage":"Could not read MessagePack data for %{indirection} %{key}: %{detail}","messagePattern":"Could not read MessagePack data for %(.+?) %(.+?): %(.+?)","errorType":"exception","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/indirector/msgpack.rb","lineNumber":70,"sourceCode":"      raise ArgumentError, _(\"invalid key\")\n    end\n\n    base = Puppet.run_mode.server? ? Puppet[:server_datadir] : Puppet[:client_datadir]\n    File.join(base, self.class.indirection_name.to_s, name.to_s + ext)\n  end\n\n  private\n\n  def load_msgpack_from_file(file, key)\n    msgpack = nil\n\n    begin\n      msgpack = Puppet::FileSystem.read(file, :encoding => 'utf-8')\n    rescue Errno::ENOENT\n      return nil\n    rescue => detail\n      # TRANSLATORS \"MessagePack\" is a program name and should not be translated\n      raise Puppet::Error, _(\"Could not read MessagePack data for %{indirection} %{key}: %{detail}\") % { indirection: indirection.name, key: key, detail: detail }, detail.backtrace\n    end\n\n    begin\n      from_msgpack(msgpack)\n    rescue => detail\n      raise Puppet::Error, _(\"Could not parse MessagePack data for %{indirection} %{key}: %{detail}\") % { indirection: indirection.name, key: key, detail: detail }, detail.backtrace\n    end\n  end\n\n  def from_msgpack(text)\n    model.convert_from('msgpack', text)\n  end\n\n  def to_msgpack(object)\n    object.render('msgpack')\n  end\nend\n","sourceCodeStart":52,"sourceCodeEnd":88,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/indirector/msgpack.rb#L52-L88","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect the %{detail} in the message to confirm the errno (EACCES vs EISDIR) and check the exact file path shown in the error","Fix ownership/permissions of the cache tree: chown -R <puppet-user> <vardir> && find <vardir> -type f -exec chmod 644 {} +","Delete the stale cache file (rm <vardir>/<indirection>/<key>.msgpack) so the next find regenerates it from the source of truth","If SELinux is enforcing, run restorecon -Rv on the vardir or check audit.log for denials","Reconsider whether the msgpack terminus is intended; the default cached-catalog format is json, which avoids the msgpack gem dependency entirely"],"exampleFix":"# before (agent fails reading root-owned cache file)\nsudo puppet agent -t   # creates /var/cache/puppet/catalog/x.msgpack as root:root 0600\n# later, puppet service (user puppet) hits:\n#   Error: Could not read MessagePack data for catalog mynode: Permission denied\n\n# after: normalize cache ownership and clear stale entries\nchown -R puppet:puppet $(puppet config print vardir)\nfind $(puppet config print vardir) -name '*.msgpack' -delete\nsystemctl restart puppet","handlingStrategy":"try-catch","validationCode":"file = File.join(Puppet[:vardir].to_s, indirection_name, \"#{key}.msgpack\")\nreturn if Puppet::FileSystem.exist?(file) && !Puppet::FileSystem.readable?(file) ? false : true","typeGuard":null,"tryCatchPattern":"begin\n  result = Puppet::Resource::Catalog.indirection.find(node)\nrescue Puppet::Error => e\n  raise unless e.message.start_with?('Could not read MessagePack data')\n  Puppet.warning \"msgpack cache unreadable, clearing and retrying once: #{e.message}\"\n  File.delete(cache_path) rescue nil\n  result = Puppet::Resource::Catalog.indirection.find(node)\nend","preventionTips":["Run the puppet agent under a single dedicated user so all cache files share one owner","After any manual 'sudo puppet agent -t', chown the vardir back to the service user","Monitor vardir permissions in your config-management baseline (file resources with owner/mode)"],"tags":["puppet","msgpack","cache","file-permissions","indirector"],"backgroundTag":"file-read-permission-denied","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}