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

Failed to call LookupAccountSidW with bytes: %{sid_bytes}

Error message

Failed to call LookupAccountSidW with bytes: %{sid_bytes}

What it means

Raised by Principal.lookup_account_sid (lib/puppet/util/windows/principal.rb:131) when the Win32 LookupAccountSidW call fails while translating SID bytes into an account/domain name. Note that the byte array has already passed an IsValidSid check earlier in the method, so the SID is structurally valid — failure means lookup failure: ERROR_NONE_MAPPED (1332) for SIDs with no owning account (deleted users, orphaned SIDs), or domain/trust errors for foreign SIDs.

Source

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

                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

                success = LookupAccountSidW(system_name_ptr, sid_ptr, FFI::Pointer::NULL, name_length_ptr,
                                            FFI::Pointer::NULL, domain_length_ptr, name_use_enum_ptr)
                last_error = FFI.errno

                if success == FFI::WIN32_FALSE && last_error != ERROR_INSUFFICIENT_BUFFER
                  raise Puppet::Util::Windows::Error.new(_('Failed to call LookupAccountSidW with bytes: %{sid_bytes}') % { sid_bytes: sid_bytes }, last_error)
                end

                FFI::MemoryPointer.new(:lpwstr, name_length_ptr.read_dword) do |name_ptr|
                  FFI::MemoryPointer.new(:lpwstr, domain_length_ptr.read_dword) do |domain_ptr|
                    if LookupAccountSidW(system_name_ptr, sid_ptr, name_ptr, name_length_ptr,
                                         domain_ptr, domain_length_ptr, name_use_enum_ptr) == FFI::WIN32_FALSE
                      raise Puppet::Util::Windows::Error, _('Failed to call LookupAccountSidW with bytes: %{sid_bytes}') % { sid_bytes: sid_bytes }
                    end

                    return new(
                      name_ptr.read_wide_string(name_length_ptr.read_dword),
                      sid_bytes,
                      Puppet::Util::Windows::SID.sid_ptr_to_string(sid_ptr),
                      domain_ptr.read_wide_string(domain_length_ptr.read_dword),
                      SID_NAME_USE[name_use_enum_ptr.read_uint32]
                    )
                  end
                end
              end
            end
          end
        end
      ensure
        system_name_ptr.free if system_name_ptr != FFI::Pointer::NULL
      end

View on GitHub (pinned to e227c27540)

Solutions

  1. Rescue Puppet::Util::Windows::Error and treat e.code == 1332 (ERROR_NONE_MAPPED) as 'account gone' rather than a hard failure.
  2. When starting from a SID string, use SID.name_to_principal(name, true) — allow_unresolved returns an unresolved Principal instead of raising.
  3. For domain SIDs, verify trust and DC reachability (nltest /sc_query:<domain>) before failing.
  4. Clean up orphaned SIDs in local groups if they pollute the data you process.

Example fix

# before
principal = Principal.lookup_account_sid(sid_bytes)

# after — tolerate unresolvable (orphaned) SIDs
begin
  principal = Principal.lookup_account_sid(sid_bytes)
rescue Puppet::Util::Windows::Error => e
  raise unless e.code == 1332 # ERROR_NONE_MAPPED
  principal = nil
end
Defensive patterns

Strategy: try-catch

Validate before calling

# If the SID originated as a string, confirm it converts before resolving
Puppet::Util::Windows::SID.string_to_sid_ptr(sid_string) do |ptr|
  raise ArgumentError, "invalid SID string #{sid_string}" if Puppet::Util::Windows::SID.IsValidSid(ptr) == FFI::WIN32_FALSE
end

Try / catch

begin
  principal = Principal.lookup_account_sid(sid_bytes)
rescue Puppet::Util::Windows::Error => e
  raise unless e.code == 1332 # ERROR_NONE_MAPPED — orphaned SID
  principal = nil # or build an unresolved marker
end

Prevention

When it happens

Trigger: Resolving a SID whose account was deleted (orphaned SID in a DACL or local group); a domain SID from an untrusted or unreachable domain (ERROR_TRUSTED_DOMAIN_FAILURE 1788 / ERROR_TRUSTED_RELATIONSHIP_FAILURE 1789); the second LookupAccountSidW call failing after the sizing pass returned only ERROR_INSUFFICIENT_BUFFER.

Common situations: Local groups containing removed domain users (common after domain cleanups); DACLs carrying SIDs from other machines or stale backups; disjoined hosts resolving domain SIDs; SID arrays copied between environments.

Related errors


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