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

  1. Replace numeric entries with the group's name: `groups => ['developers']`
  2. If the group itself must exist with that GID, manage it separately via `group { 'developers': gid => 1001 }` and reference the name
  3. 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

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


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