puppetlabs/puppet · error · ArgumentError
Group names must be provided, not GID numbers.
Error message
Group names must be provided, not GID numbers.
What it means
Raised by the validate block of the `groups` property (a Puppet::Property::List) on the `user` type. Each group entry must be a name; the check `/^\d+$/` rejects any member that is purely digits, i.e. a GID. Puppet resolves supplementary groups by name only, because the target system's GID numbering is not assumed to match the manifest's.
Source
Thrown at lib/puppet/type/user.rb:347
value
end
end
validate do |value|
if value.to_s !~ /^-?\d+$/
raise ArgumentError, "Password warning days must be provided as a number."
end
end
end
newproperty(:groups, :parent => Puppet::Property::List) do
desc "The groups to which the user belongs. The primary group should
not be listed, and groups should be identified by name rather than by
GID. Multiple groups should be specified as an array."
validate do |value|
if value =~ /^\d+$/
raise ArgumentError, _("Group names must be provided, not GID numbers.")
end
raise ArgumentError, _("Group names must be provided as an array, not a comma-separated list.") if value.include?(",")
raise ArgumentError, _("Group names must not be empty. If you want to specify \"no groups\" pass an empty array") if value.empty?
end
def change_to_s(currentvalue, newvalue)
newvalue = newvalue.split(",") if newvalue != :absent
if provider.respond_to?(:groups_to_s)
# for Windows ADSI
# de-dupe the "newvalue" when the sync event message is generated,
# due to final retrieve called after the resource has been modified
newvalue = provider.groups_to_s(newvalue).split(',').uniq
end
super(currentvalue, newvalue)
end
View on GitHub (pinned to e227c27540)
Solutions
- Replace numeric entries with the group's name: `groups => ['developers']`
- If the group itself must exist with that GID, manage it separately via `group { 'developers': gid => 1001 }` and reference the name
- For genuinely numeric group names on the target OS, quote is not enough — use a non-numeric name or manage membership outside this property
Example fix
# before
user { 'alice':
ensure => present,
groups => ['1001', '1002'],
}
# after
group { 'developers': ensure => present, gid => 1001 }
group { 'qa': ensure => present, gid => 1002 }
user { 'alice':
ensure => present,
groups => ['developers', 'qa'],
} Defensive patterns
Strategy: validation
Validate before calling
# Before building the resource, assert no group entry is all digits
bad = groups.select { |g| g.to_s.match?(/\A\d+\z/) }
raise ArgumentError, "groups must be names, not GIDs: #{bad.join(', ')}" unless bad.empty? Type guard
def group_names?(list)
list.is_a?(Array) && list.all? { |g| g.is_a?(String) && !g.match?(/\A\d+\z/) && !g.empty? && !g.include?(',') }
end Prevention
- Store group lists in Hiera as arrays of names
- Add a lint/CI check that rejects all-digit group entries in user data
- Manage the groups themselves with the group type (with explicit gid) and reference them by name
When it happens
Trigger: `user { 'alice': groups => ['1001'] }` or `groups => '1001'`; converting /etc/group entries directly into manifest data; group names that really are numeric strings are also rejected because they cannot be distinguished from GIDs.
Common situations: Porting legacy /etc/passwd-/etc/group-based setup scripts into Puppet; CMDB exports that store numeric group IDs; creating users whose group names are the company employee number.
Related errors
- Could not reset the groups property back to %{cur_groups} af
- Password warning days must be provided as a number.
- Group names must be provided as an array, not a comma-separa
- Group names must not be empty. If you want to specify "no gr
- Role names must be provided, not numbers
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/597cf421d1fc07d5.
Report an issue: GitHub.