puppetlabs/puppet · error · Puppet::Util::Windows::Error

Invalid SID

Error message

Invalid SID

What it means

Raised by Puppet::Util::Windows::User.check_token_membership as a defensive post-condition: CreateWellKnownSid claimed success but the produced buffer fails IsValidSid. It guards against feeding a garbage SID into CheckTokenMembership. Since the input is a constant well-known SID type, hitting this implies corrupted output memory or an API contract violation, not bad input.

Source

Thrown at lib/puppet/util/windows/user.rb:60

  # logon for a separate reason
  ERROR_ACCOUNT_RESTRICTION = 1327
  ERROR_INVALID_LOGON_HOURS = 1328
  ERROR_INVALID_WORKSTATION = 1329
  ERROR_ACCOUNT_DISABLED    = 1331

  def check_token_membership
    is_admin = false
    FFI::MemoryPointer.new(:byte, SECURITY_MAX_SID_SIZE) do |sid_pointer|
      FFI::MemoryPointer.new(:dword, 1) do |size_pointer|
        size_pointer.write_uint32(SECURITY_MAX_SID_SIZE)

        if CreateWellKnownSid(:WinBuiltinAdministratorsSid, FFI::Pointer::NULL, sid_pointer, size_pointer) == FFI::WIN32_FALSE
          raise Puppet::Util::Windows::Error, _("Failed to create administrators SID")
        end
      end

      if IsValidSid(sid_pointer) == FFI::WIN32_FALSE
        raise Puppet::Util::Windows::Error, _("Invalid SID")
      end

      FFI::MemoryPointer.new(:win32_bool, 1) do |ismember_pointer|
        if CheckTokenMembership(FFI::Pointer::NULL_HANDLE, sid_pointer, ismember_pointer) == FFI::WIN32_FALSE
          raise Puppet::Util::Windows::Error, _("Failed to check membership")
        end

        # Is administrators SID enabled in calling thread's access token?
        is_admin = ismember_pointer.read_win32_bool
      end
    end

    is_admin
  end
  module_function :check_token_membership

  def password_is?(name, password, domain = '.')
    logon_user(name, password, domain) { |token| }

View on GitHub (pinned to e227c27540)

Solutions

  1. In test doubles, write a minimal valid SID into the buffer (first byte Revision = 1).
  2. Restart the agent if native corruption is suspected in production.
  3. Capture a crash dump if it recurs to identify the component corrupting memory.
  4. Do not attempt caller-side workarounds — the inputs are constants.

Example fix

// exampleFix not applicable - defensive internal check
null
Defensive patterns

Strategy: try-catch

Try / catch

begin
  Puppet::Util::Windows::User.check_token_membership
rescue Puppet::Util::Windows::Error => e
  raise unless e.message == 'Invalid SID'
  Puppet.warning('CreateWellKnownSid returned garbage; possible native memory corruption')
  nil
end

Prevention

When it happens

Trigger: The freshly created SID buffer being corrupted between the two calls — native memory overwrite by another extension, broken advapi32 behavior on emulation layers, or a mocked FFI layer in tests returning success while leaving the buffer zeroed (zeroed memory fails IsValidSid because Revision is 0).

Common situations: Spec suites stubbing CreateWellKnownSid without writing a valid Revision byte into the buffer; a loaded native gem stomping the stack/heap of the Puppet process. Essentially never occurs on healthy systems.

Related errors


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