puppetlabs/puppet · error · ArgumentError
invalid key
Error message
invalid key
What it means
Before touching disk, the MessagePack terminus validates the key against Puppet::Indirector::BadNameRegexp, which matches a leading '..', any '/' or '\\', a NUL byte, or a leading Windows drive-letter prefix. A match means the key could escape the indirection's data directory (directory traversal), so Puppet logs crit 'directory traversal detected in <class>: <name>' and raises ArgumentError 'invalid key'.
Source
Thrown at lib/puppet/indirector/msgpack.rb:52
rescue => detail
unless detail.is_a? Errno::ENOENT
raise Puppet::Error, _("Could not destroy %{name} %{request}: %{detail}") % { name: name, request: request.key, detail: detail }, detail.backtrace
end
1 # emulate success...
end
def search(request)
Dir.glob(path(request.key)).collect do |file|
load_msgpack_from_file(file, request.key)
end
end
# Return the path to a given node's file.
def path(name, ext = '.msgpack')
if name =~ Puppet::Indirector::BadNameRegexp then
Puppet.crit(_("directory traversal detected in %{indirection}: %{name}") % { indirection: self.class, name: name.inspect })
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.backtraceView on GitHub (pinned to e227c27540)
Solutions
- Sanitize the key before the call: replace path separators, NULs, and leading '..' sequences.
- Encode special identifiers (URL-encode or digest) rather than passing them raw.
- Validate names at your API boundary and reject bad ones early.
- Change the naming scheme if provisioning produces keys with separators.
Example fix
# before
indirection.destroy('web/server01')
# crit: directory traversal detected ... ArgumentError: invalid key
# after
safe_key = 'web/server01'.tr('/', '_')
indirection.destroy(safe_key) Defensive patterns
Strategy: validation
Validate before calling
raise ArgumentError, 'unsafe key ' + key.inspect if key.to_s.match?(Puppet::Indirector::BadNameRegexp)
safe_key = key.tr('/', '_') Type guard
def safe_indirector_key?(name) name.is_a?(String) && !name.match?(Puppet::Indirector::BadNameRegexp) end
Prevention
- Never accept raw user input as an indirector key.
- Validate identifiers for separators, NULs, and drive prefixes at the boundary.
- Alert on the crit log 'directory traversal detected' - it indicates hostile or broken input.
When it happens
Trigger: Calling find/save/destroy on a msgpack-backed indirection with a key containing a slash, a leading '..', an absolute path, a NUL byte, or a 'C:'-style Windows drive prefix.
Common situations: Certnames or identifiers containing separators fed straight from user input; code reusing file paths as keys; cross-platform names accidentally carrying a drive-letter prefix.
Related errors
- invalid key
- invalid key
- Attempt to install file with an invalid path into %{path} un
- Could not destroy %{name} %{request}: %{detail}
- Could not read MessagePack data for %{indirection} %{key}: %
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/c88a39daa0630d10.
Report an issue: GitHub.