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

Failed to check membership

Error message

Failed to check membership

What it means

Raised by Puppet::Util::Windows::User.check_token_membership when CheckTokenMembership itself fails (returns FALSE). CheckTokenMembership examines the effective token to test whether the administrators SID is enabled; failure means the API could not evaluate the token, which GetLastError (attached by Puppet::Util::Windows::Error) explains — commonly ERROR_NO_TOKEN when there is no impersonation/effective token to check.

Source

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

  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| }
  rescue Puppet::Util::Windows::Error => detail
    authenticated_error_codes = Set[
      ERROR_ACCOUNT_RESTRICTION,
      ERROR_INVALID_LOGON_HOURS,
      ERROR_INVALID_WORKSTATION,

View on GitHub (pinned to e227c27540)

Solutions

  1. Read the Win32 code from the exception (e.code) — ERROR_NO_TOKEN vs ERROR_ACCESS_DENIED point to different fixes.
  2. Run the check from an interactive/elevated context to confirm the environment, then adjust the hosting context for the failing one.
  3. For ERROR_NO_TOKEN, ensure the thread/process actually has a token (not a bare system thread).
  4. In tests, stub CheckTokenMembership to succeed and write TRUE/FALSE into ismember_pointer.

Example fix

# before
is_admin = Puppet::Util::Windows::User.check_token_membership

# after - degrade gracefully when the token cannot be evaluated
begin
  is_admin = Puppet::Util::Windows::User.check_token_membership
rescue Puppet::Util::Windows::Error => e
  Puppet.warning("Cannot determine admin status: Win32 #{e.code}")
  is_admin = nil
end
Defensive patterns

Strategy: try-catch

Try / catch

begin
  is_admin = Puppet::Util::Windows::User.check_token_membership
rescue Puppet::Util::Windows::Error => e
  case e.code
  when 1008 # ERROR_NO_TOKEN: no effective token in this context
    is_admin = nil
  else raise
  end
end

Prevention

When it happens

Trigger: Calling check_token_membership from a context with no access token (some service/session-0 corner cases), an invalid token handle environment, or access-denied while duplicating the token; also mocked FFI in tests returning FALSE.

Common situations: Running Puppet code from minimal service hosts or scheduled-task contexts with unusual token setups; userspace emulation layers; spec environments where CheckTokenMembership is stubbed as failing.

Related errors


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