puppetlabs/puppet · error · LoadError
The 'getgrouplist' method is not available
Error message
The 'getgrouplist' method is not available
What it means
Puppet::Util::POSIX#get_groups_list (posix.rb:39) raises LoadError when Puppet::FFI::POSIX::Functions does not respond to getgrouplist, i.e. the FFI binding for getgrouplist(3) is absent (platform without the libc call, ffi gem missing/broken, or restricted load). Important context: the public caller groups_of (posix.rb:15-26) rescues StandardError and LoadError, logs 'Falling back to Puppet::Etc.group', and iterates the group database instead, so seeing this error escape means someone called the private helper directly or the fallback path itself is broken.
Source
Thrown at lib/puppet/util/posix.rb:39
groups = []
Puppet::Etc.group do |group|
groups << group.name if group.mem.include?(user)
end
end
uniq_groups = groups.uniq
if uniq_groups != groups
Puppet.debug(_('Removing any duplicate group entries'))
end
uniq_groups
end
private
def get_groups_list(user)
raise LoadError, "The 'getgrouplist' method is not available" unless Puppet::FFI::POSIX::Functions.respond_to?(:getgrouplist)
user_gid = Puppet::Etc.getpwnam(user).gid
ngroups = Puppet::FFI::POSIX::Constants::MAXIMUM_NUMBER_OF_GROUPS
loop do
FFI::MemoryPointer.new(:int) do |ngroups_ptr|
FFI::MemoryPointer.new(:uint, ngroups) do |groups_ptr|
old_ngroups = ngroups
ngroups_ptr.write_int(ngroups)
if Puppet::FFI::POSIX::Functions.getgrouplist(user, user_gid, groups_ptr, ngroups_ptr) != -1
groups_gids = groups_ptr.get_array_of_uint(0, ngroups_ptr.read_int)
result = []
groups_gids.each do |group_gid|
group_info = Puppet::Etc.getgrgid(group_gid)
result |= [group_info.name] if group_info.mem.include?(user)
endView on GitHub (pinned to e227c27540)
Solutions
- Use the public Puppet::Util::POSIX.groups_of(user), which already falls back to Puppet::Etc.group iteration.
- Ensure the ffi gem is installed and loadable: gem install ffi; ruby -e "require 'ffi'".
- On the problem host, verify the symbol exists: ruby -e "require 'puppet/ffi/posix'; p Puppet::FFI::POSIX::Functions.respond_to?(:getgrouplist)".
- If the platform genuinely lacks getgrouplist (e.g., Windows), branch to Puppet::Util::Windows or Etc-based enumeration instead of the FFI path.
Example fix
// before groups = obj.send(:get_groups_list, user) # bypasses the guarded path, raises LoadError // after groups = Puppet::Util::POSIX.groups_of(user) # FFI path with automatic Etc.group fallback
Defensive patterns
Strategy: validation
Validate before calling
require 'puppet/ffi/posix' rescue nil ffi_ok = defined?(Puppet::FFI::POSIX::Functions) && Puppet::FFI::POSIX::Functions.respond_to?(:getgrouplist)
Try / catch
begin
groups = Puppet::Util::POSIX.groups_of(user)
rescue LoadError => e
Puppet.warning("FFI group lookup unavailable (#{e.message}); using Etc fallback")
groups = Puppet::Etc.group.select { |g| g.mem.include?(user) }.map(&:name)
end Prevention
- Always call the public groups_of; it has the built-in Etc fallback.
- Smoke-test ffi on new images: ruby -e "require 'ffi'".
- Branch per-platform before touching POSIX FFI helpers.
When it happens
Trigger: Calling get_groups_list/send(:get_groups_list, user) directly on Windows (no getgrouplist), on a platform where the ffi gem failed to install, or when libffi cannot bind the symbol (hardened libc, missing headers at gem build time). Calling groups_of on such a platform only logs a debug fallback, it does not raise.
Common situations: Running Puppet code on unsupported/minimal containers (alpine without libffi), FFI gem compiled against an incompatible libc after a system upgrade, custom user/group providers invoking POSIX groups handling outside Puppet's own guarded path.
Related errors
- No such group %{group}
- RegisterEventSourceW failed to open Windows eventlog
- ReportEventW failed to report event to Windows eventlog
- Cannot determine basic system flavour
- This version of Windows does not support symlinks. Windows
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/2e471a9085136166.
Report an issue: GitHub.