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

Failed to call LookupAccountNameW with account: %{account_na

Error message

Failed to call LookupAccountNameW with account: %{account_name}

What it means

Raised by Puppet::Util::Windows::Principal.lookup_account_name (lib/puppet/util/windows/principal.rb:76) when the Win32 LookupAccountNameW API cannot resolve an account name into a SID. The sizing call is only allowed to fail with ERROR_INSUFFICIENT_BUFFER (122); any other code on the first call, or any failure of the second real lookup call, raises Puppet::Util::Windows::Error carrying the account name. The exception exposes the Win32 code as Error#code and its message is suffixed with FormatMessageW text. In practice it means the name is unknown on this host or its domain, or the domain cannot be queried.

Source

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

        FFI::MemoryPointer.from_string_to_wide_string(account_name) do |account_name_ptr|
          FFI::MemoryPointer.new(:byte, MAXIMUM_SID_BYTE_LENGTH) do |sid_ptr|
            FFI::MemoryPointer.new(:dword, 1) do |sid_length_ptr|
              FFI::MemoryPointer.new(:dword, 1) do |domain_length_ptr|
                FFI::MemoryPointer.new(:uint32, 1) do |name_use_enum_ptr|
                  sid_length_ptr.write_dword(MAXIMUM_SID_BYTE_LENGTH)
                  success = LookupAccountNameW(system_name_ptr, account_name_ptr, sid_ptr, sid_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 LookupAccountNameW with account: %{account_name}') % { account_name: account_name }, last_error)
                  end

                  FFI::MemoryPointer.new(:lpwstr, domain_length_ptr.read_dword) do |domain_ptr|
                    if LookupAccountNameW(system_name_ptr, account_name_ptr,
                                          sid_ptr, sid_length_ptr,
                                          domain_ptr, domain_length_ptr, name_use_enum_ptr) == FFI::WIN32_FALSE
                      raise Puppet::Util::Windows::Error, _('Failed to call LookupAccountNameW with account: %{account_name}') % { account_name: account_name }
                    end

                    # with a SID returned, loop back through lookup_account_sid to retrieve official name
                    # necessary when accounts like . or '' are passed in
                    return lookup_account_sid(
                      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

View on GitHub (pinned to e227c27540)

Solutions

  1. Resolve safely first: Puppet::Util::Windows::SID.name_to_sid / name_to_principal return nil instead of raising when the account is unknown.
  2. Verify the account on the host itself: net user <name> for local accounts, net user <name> /domain or whoami /user for domain accounts.
  3. Use fully qualified names (DOMAIN\user or COMPUTERNAME\user) instead of bare ambiguous names.
  4. For domain accounts confirm DC reachability and trust with nltest /dsgetdc:<domain> and nltest /sc_query:<domain>; repair the trust or rejoin if they fail.
  5. Rescue Puppet::Util::Windows::Error and branch on e.code: 1332 means no mapping, 1788/1789 mean domain/trust failure.

Example fix

# before — raises when the account is unknown
principal = Principal.lookup_account_name(account_name)

# after — use the non-raising resolver and handle nil explicitly
sid = Puppet::Util::Windows::SID.name_to_sid(account_name)
if sid.nil?
  Puppet.err "Account #{account_name} does not resolve on this host"
else
  principal = Puppet::Util::Windows::SID.name_to_principal(account_name)
end
Defensive patterns

Strategy: try-catch

Validate before calling

# name_to_sid resolves without raising; nil means unknown account
if Puppet::Util::Windows::SID.name_to_sid(account_name).nil?
  Puppet.err "Unresolvable account: #{account_name}"
  return
end

Try / catch

begin
  principal = Principal.lookup_account_name(account_name)
rescue Puppet::Util::Windows::Error => e
  case e.code
  when 1332 then Puppet.err "No mapping for #{account_name} (ERROR_NONE_MAPPED)"
  when 1788, 1789 then Puppet.err "Domain trust failure for #{account_name}: #{e.message}"
  else raise
  end
end

Prevention

When it happens

Trigger: Calling Principal.lookup_account_name with a nonexistent or misspelled account; a DOMAIN\user name for an untrusted or unreachable domain; the process running under LOCAL SERVICE or a detached SYSTEM context that cannot reach a domain controller (ERROR_NONE_MAPPED 1332 or trust errors 1788/1789); the second LookupAccountNameW call failing after the sizing pass.

Common situations: ACL/security manifests referencing deleted or renamed users and groups; broken Active Directory trust or lost secure channel; machine disjoined from the domain while manifests still use domain accounts; agent running as a service with no network path to a DC during catalog application.

Related errors


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