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

GetTokenInformation(#{token_handle}, #{token_information}, n

Error message

GetTokenInformation(#{token_handle}, #{token_information}, nil, 0, #{return_length_ptr})

What it means

Raised by Process.get_token_information (lib/puppet/util/windows/process.rb:176) when the sizing pass of GetTokenInformation leaves return_length <= 0. The code infers failure from the length rather than the return BOOL, so this means the first call accomplished nothing: the token handle is invalid or closed, lacks TOKEN_QUERY access, or the token information class passed is not valid on this OS.

Source

Thrown at lib/puppet/util/windows/process.rb:176

        raise Puppet::Util::Windows::Error, "LookupPrivilegeValue(#{system_name}, #{name}, #{luid_ptr})"
      end

      yield LUID.new(luid_ptr)
    end

    # the underlying MemoryPointer for LUID is cleaned up by this point
    nil
  end
  module_function :lookup_privilege_value

  def get_token_information(token_handle, token_information, &block)
    # to determine buffer size
    FFI::MemoryPointer.new(:dword, 1) do |return_length_ptr|
      result = GetTokenInformation(token_handle, token_information, nil, 0, return_length_ptr)
      return_length = return_length_ptr.read_dword

      if return_length <= 0
        raise Puppet::Util::Windows::Error, "GetTokenInformation(#{token_handle}, #{token_information}, nil, 0, #{return_length_ptr})"
      end

      # re-call API with properly sized buffer for all results
      FFI::MemoryPointer.new(return_length) do |token_information_buf|
        result = GetTokenInformation(token_handle, token_information,
                                     token_information_buf, return_length, return_length_ptr)

        if result == FFI::WIN32_FALSE
          raise Puppet::Util::Windows::Error, "GetTokenInformation(#{token_handle}, #{token_information}, #{token_information_buf}, " \
                                              "#{return_length}, #{return_length_ptr})"
        end

        yield token_information_buf
      end
    end

    # GetTokenInformation buffer has been cleaned up by this point, nothing to return
    nil

View on GitHub (pinned to e227c27540)

Solutions

  1. Keep all token reads inside the open_process_token block — the handle's lifetime is that block.
  2. Open the token with TOKEN_QUERY included (TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES when adjusting privileges).
  3. Verify the token information class (e.g. :TokenUser, :TokenPrivileges, :TokenElevation) is spelled and valued correctly.
  4. Rescue and inspect e.code — 6 (invalid handle) points at lifetime bugs, 5 (access denied) at the mask.

Example fix

# before — handle escapes its block and is already closed
Process.open_process_token(h, 0x20) { |t| saved = t }
Process.get_token_information(saved, :TokenUser)

# after — query inside the block, with TOKEN_QUERY
Process.open_process_token(h, Process::TOKEN_QUERY | 0x20) do |t|
  Process.get_token_information(t, :TokenUser) { |buf| use(buf) }
end
Defensive patterns

Strategy: try-catch

Validate before calling

# ensure the access mask includes TOKEN_QUERY before any information read
mask |= Process::TOKEN_QUERY if (mask & Process::TOKEN_QUERY).zero?
Process.open_process_token(handle, mask) { |t| Process.get_token_information(t, info_class) { |b| use(b) } }

Try / catch

begin
  Process.get_token_information(token, info_class) { |buf| use(buf) }
rescue Puppet::Util::Windows::Error => e
  Puppet.err "token query #{info_class} failed (#{e.code}): #{e.message}"
  nil
end

Prevention

When it happens

Trigger: Passing a token handle that has already been closed (open_process_token closes it when its block ends); opening a token with only TOKEN_ADJUST_PRIVILEGES and then reading information from it; requesting a Token* class unsupported on the Windows version; passing a bogus class symbol.

Common situations: Saving the token handle into a variable used after the open_process_token block; privilege-enabling code that never asks for TOKEN_QUERY; version drift in token class names/values.

Related errors


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