{"record":{"id":"746dc3185ac02075","repo":"puppetlabs/puppet","slug":"no-such-group-group","errorCode":null,"errorMessage":"No such group %{group}","messagePattern":"No such group %(.+?)","errorType":"exception","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/suidmanager.rb","lineNumber":103,"sourceCode":"  def change_privileges(uid = nil, gid = nil, permanently = false)\n    return unless uid or gid\n\n    unless gid\n      uid = convert_xid(:uid, uid)\n      gid = Etc.getpwuid(uid).gid\n    end\n\n    change_group(gid, permanently)\n    change_user(uid, permanently) if uid\n  end\n  module_function :change_privileges\n\n  # Changes the egid of the process if `permanently` is not set, otherwise\n  # changes gid. This method will fail if used on Windows, or attempting to\n  # change to a different gid without root.\n  def change_group(group, permanently = false)\n    gid = convert_xid(:gid, group)\n    raise Puppet::Error, _(\"No such group %{group}\") % { group: group } unless gid\n\n    return if Process.egid == gid\n\n    if permanently\n      Process::GID.change_privilege(gid)\n    else\n      Process.egid = gid\n    end\n  end\n  module_function :change_group\n\n  # As change_group, but operates on uids. If changing user permanently,\n  # supplementary groups will be set the to default groups for the new uid.\n  def change_user(user, permanently = false)\n    uid = convert_xid(:uid, user)\n    raise Puppet::Error, _(\"No such user %{user}\") % { user: user } unless uid\n\n    return if Process.euid == uid","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/suidmanager.rb#L85-L121","documentation":"Puppet::Util::SUIDManager.change_group (suidmanager.rb:103) resolves the group via convert_xid(:gid, group) (Integers pass through; names go through Puppet::Util.gid -> getgrnam/getgrgid lookups) and raises Puppet::Error 'No such group <group>' when the result is falsy. Reached from change_privileges/asuser, which back the 'run as another user/group' behavior of exec resources and privilege-dropping code. In the current code the unresolvable-name case usually raises the earlier 'Invalid group' from convert_xid, so this line is the backstop when the gid lookup yields nil/false without that raise (or on older Puppet revisions).","triggerScenarios":"change_privileges(uid, 'myapp') when group myapp does not exist yet; change_group(12345) for a gid absent from /etc/group; exec resource with group => before the group resource has been realized; NSS/LDAP group resolution broken so getgrnam returns nil.","commonSituations":"Ordering: an exec that drops to a service group runs before the package creating that group; typos in group names in manifests; hosts not joined to the directory providing the group; containers missing the group entry the manifest assumes.","solutions":["Ensure the group exists first: add a group resource and make the exec depend on it (require => Group['myapp']).","Verify resolution on the host: getent group myapp (covers NSS/LDAP) or Puppet::Etc.getgrnam in Ruby.","Pass the numeric gid when the name is not stable across systems.","Rescue Puppet::Error around privilege change and report both the group and the result of getent for the node."],"exampleFix":"// before\nexec { 'migrate':\n  command => '/usr/local/bin/migrate',\n  group   => 'myapp',   # group not yet created when this runs\n}\n\n// after\ngroup { 'myapp': ensure => present }\nexec { 'migrate':\n  command => '/usr/local/bin/migrate',\n  group   => 'myapp',\n  require => Group['myapp'],\n}","handlingStrategy":"validation","validationCode":"gid = group.is_a?(Integer) ? group : Puppet::Util::POSIX.gid(group)\nraise ArgumentError, \"group #{group} does not resolve on this node (check getent group)\" if gid.nil?\nPuppet::Util::SUIDManager.change_group(group)","typeGuard":null,"tryCatchPattern":"begin\n  Puppet::Util::SUIDManager.change_group(group, permanently)\nrescue Puppet::Error => e\n  raise unless e.message =~ /No such group/\n  raise Puppet::Error, \"#{e.message} — is the group resource realized and NSS/LDAP reachable?\"\nend","preventionTips":["Declare the group resource and require it from any exec that drops privileges to it.","Verify with `getent group <name>` during provisioning; it exercises the same NSS path puppet uses.","Prefer explicit gids in manifests when group names differ across distros."],"tags":["puppet","posix","groups","privilege-drop","suid","user-lookup"],"backgroundTag":"user-group-not-found","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}