puppetlabs/puppet · error · Puppet::Error

Invalid registry key '%{name}'

Error message

Invalid registry key '%{name}'

What it means

Raised by Puppet::Util::Windows::Registry.root (lib/puppet/util/windows/registry.rb:25) when Win32::Registry.const_get(name) throws NameError — the name is not a hive constant — re-raised as Puppet::Error with the original backtrace chained. Valid names are the full, case-sensitive Win32::Registry constants (HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER, HKEY_CLASSES_ROOT, HKEY_USERS, HKEY_PERFORMANCE_DATA, HKEY_CURRENT_CONFIG, HKEY_DYN_DATA); abbreviations like HKLM and PowerShell-style 'HKLM:' paths fail.

Source

Thrown at lib/puppet/util/windows/registry.rb:25

    require 'ffi'
    extend FFI::Library

    # https://msdn.microsoft.com/en-us/library/windows/desktop/aa384129(v=vs.85).aspx
    KEY64 = 0x100
    KEY32 = 0x200

    KEY_READ       = 0x20019
    KEY_WRITE      = 0x20006
    KEY_ALL_ACCESS = 0x2003f

    ERROR_NO_MORE_ITEMS = 259

    WCHAR_SIZE = FFI.type_size(:wchar)

    def root(name)
      Win32::Registry.const_get(name)
    rescue NameError => e
      raise Puppet::Error, _("Invalid registry key '%{name}'") % { name: name }, e.backtrace
    end

    def open(name, path, mode = KEY_READ | KEY64, &block)
      hkey = root(name)
      begin
        hkey.open(path, mode) do |subkey|
          return yield subkey
        end
      rescue Win32::Registry::Error => error
        raise Puppet::Util::Windows::Error.new(_("Failed to open registry key '%{key}\\%{path}'") % { key: hkey.keyname, path: path }, error.code, error)
      end
    end

    def keys(key)
      keys = {}
      each_key(key) { |subkey, filetime| keys[subkey] = filetime }
      keys
    end

View on GitHub (pinned to e227c27540)

Solutions

  1. Use the full hive constant names expected by Win32::Registry, exactly cased.
  2. Map abbreviations before calling root(): HKLM to HKEY_LOCAL_MACHINE, HKCU to HKEY_CURRENT_USER, HKCR to HKEY_CLASSES_ROOT, HKU to HKEY_USERS, HKCC to HKEY_CURRENT_CONFIG.
  3. Upcase and strip input, then validate against the known list at the data boundary.
  4. Rescue Puppet::Error to fail with a message that echoes the offending name.

Example fix

# before
Puppet::Util::Windows::Registry.root('HKLM')

# after — normalize abbreviations first
HIVES = { 'HKLM' => 'HKEY_LOCAL_MACHINE', 'HKCU' => 'HKEY_CURRENT_USER', 'HKCR' => 'HKEY_CLASSES_ROOT',
          'HKU' => 'HKEY_USERS', 'HKCC' => 'HKEY_CURRENT_CONFIG' }
name = HIVES.fetch(name.upcase, name)
Puppet::Util::Windows::Registry.root(name)
Defensive patterns

Strategy: validation

Validate before calling

VALID_HIVES = %w[HKEY_CLASSES_ROOT HKEY_CURRENT_USER HKEY_LOCAL_MACHINE HKEY_USERS
               HKEY_PERFORMANCE_DATA HKEY_CURRENT_CONFIG HKEY_DYN_DATA].freeze
ALIASES = { 'HKLM' => 'HKEY_LOCAL_MACHINE', 'HKCU' => 'HKEY_CURRENT_USER', 'HKCR' => 'HKEY_CLASSES_ROOT',
            'HKU' => 'HKEY_USERS', 'HKCC' => 'HKEY_CURRENT_CONFIG' }.freeze
name = ALIASES.fetch(name.to_s.upcase, name.to_s)
raise ArgumentError, "invalid registry hive #{name.inspect}" unless VALID_HIVES.include?(name)

Prevention

When it happens

Trigger: Passing 'HKLM' or 'HKCU' instead of the full constant name; a nil, misspelled or whitespace-padded root arriving from manifest data; names built by concatenation with wrong casing (const_get is case-sensitive).

Common situations: Providers converting user-friendly hive shortcuts into root names; config files using PowerShell hive syntax; copy-paste between reg.exe paths (HKLM\Software\...) and Puppet data.

Related errors


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