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

Byte array for lookup_account_sid must not be nil and must b

Error message

Byte array for lookup_account_sid must not be nil and must be at least 1 byte long

What it means

Guard clause at the top of Principal.lookup_account_sid (lib/puppet/util/windows/principal.rb:100). Before any Win32 call it rejects sid_bytes that is nil, not an Array, or empty, raising Puppet::Util::Windows::Error. It is a caller-contract failure: SIDs must be passed as a non-empty Ruby Array of byte-sized integers — exactly what lookup_account_name produces via read_bytes(...).unpack('C*').

Source

Thrown at lib/puppet/util/windows/principal.rb:100

                      system_name,
                      sid_ptr.read_bytes(sid_length_ptr.read_dword).unpack('C*')
                    )
                  end
                end
              end
            end
          end
        end
      ensure
        system_name_ptr.free if system_name_ptr != FFI::Pointer::NULL
      end
    end

    def self.lookup_account_sid(system_name = nil, sid_bytes)
      system_name_ptr = FFI::Pointer::NULL
      if sid_bytes.nil? || (!sid_bytes.is_a? Array) || (sid_bytes.length == 0)
        # TRANSLATORS `lookup_account_sid` is a variable name and should not be translated
        raise Puppet::Util::Windows::Error, _('Byte array for lookup_account_sid must not be nil and must be at least 1 byte long')
      end

      begin
        if system_name
          system_name_wide = Puppet::Util::Windows::String.wide_string(system_name)
          system_name_ptr = FFI::MemoryPointer.from_wide_string(system_name_wide)
        end

        FFI::MemoryPointer.new(:byte, sid_bytes.length) do |sid_ptr|
          FFI::MemoryPointer.new(:dword, 1) do |name_length_ptr|
            FFI::MemoryPointer.new(:dword, 1) do |domain_length_ptr|
              FFI::MemoryPointer.new(:uint32, 1) do |name_use_enum_ptr|
                sid_ptr.write_array_of_uchar(sid_bytes)

                if Puppet::Util::Windows::SID.IsValidSid(sid_ptr) == FFI::WIN32_FALSE
                  raise Puppet::Util::Windows::Error.new(_('Byte array for lookup_account_sid is invalid: %{sid_bytes}') % { sid_bytes: sid_bytes }, ERROR_INVALID_PARAMETER)
                end

View on GitHub (pinned to e227c27540)

Solutions

  1. Obtain bytes from a resolved Principal: Puppet::Util::Windows::SID.name_to_principal(name).sid_bytes is always a valid byte Array.
  2. Use SID.octet_string_to_principal(bytes), which validates the shape for you.
  3. If converting from a SID string, use SID.string_to_sid_ptr and read_array_of_uchar(SID.get_length_sid(ptr)).
  4. Fix the caller to pass Array bytes (integers 0-255) and fail fast on nil upstream instead of propagating it.

Example fix

# before — string passed instead of a byte array
Principal.lookup_account_sid('S-1-5-18')

# after — bytes obtained from a resolved Principal
principal = Puppet::Util::Windows::SID.name_to_principal('SYSTEM')
bytes = principal.sid_bytes # non-empty Array of bytes
Principal.lookup_account_sid(bytes)
Defensive patterns

Strategy: validation

Validate before calling

raise ArgumentError, 'sid_bytes must be a non-empty Array' unless sid_bytes.is_a?(Array) && !sid_bytes.empty?
Principal.lookup_account_sid(sid_bytes)

Type guard

sid_bytes_valid = ->(v) { v.is_a?(Array) && !v.empty? && v.all? { |b| b.is_a?(Integer) && b.between?(0, 255) } }
raise ArgumentError, 'invalid SID byte array' unless sid_bytes_valid.call(sid_bytes)

Prevention

When it happens

Trigger: Calling lookup_account_sid with a SID string like 'S-1-5-18' instead of a byte array; passing [] because an upstream read/unpack produced nothing; passing a String of raw bytes or an FFI pointer instead of an Array.

Common situations: Custom providers hand-rolling SID handling instead of using SID.octet_string_to_principal; byte arrays built from Ruby strings without unpack('C*'); nil propagated from a failed earlier lookup (e.g. name_to_principal returning nil).

Related errors


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