{"record":{"id":"bab48ce9929f43ed","repo":"jordansissel/fpm","slug":"failed-to-find-group-for-gid-gid","errorCode":null,"errorMessage":"Failed to find group for gid #{gid}","messagePattern":"Failed to find group for gid #(.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"lib/fpm/package/puppet.rb","lineNumber":115,"sourceCode":"  def uid2user(uid)\n    begin\n      pwent = Etc.getpwuid(uid)\n      return pwent.name\n    rescue ArgumentError => e\n      # Invalid user id? No user? Return the uid.\n      logger.warn(\"Failed to find username for uid #{uid}\")\n      return uid.to_s\n    end\n  end # def uid2user\n\n  # Helper for group lookup\n  def gid2group(gid)\n    begin\n      grent = Etc.getgrgid(gid)\n      return grent.name\n    rescue ArgumentError => e\n      # Invalid user id? No user? Return the uid.\n      logger.warn(\"Failed to find group for gid #{gid}\")\n      return gid.to_s\n    end\n  end # def uid2user\nend # class FPM::Target::Puppet\n\n","sourceCodeStart":97,"sourceCodeEnd":121,"githubUrl":"https://github.com/jordansissel/fpm/blob/b6d77ba72a560b687723376a0e5115c3a92634ad/lib/fpm/package/puppet.rb#L97-L121","documentation":"fpm's Puppet output target converts each file's numeric gid into a group name for the generated manifest. gid2group calls Etc.getgrgid(gid); when the build host's group database has no entry for that gid, Ruby raises ArgumentError. fpm rescues it, logs this warning, and falls back to embedding the raw numeric gid in the puppet package. The build succeeds; only the manifest's group naming degrades.","triggerScenarios":"Running `fpm -s dir -t puppet` (or any -t puppet build) where staged files carry a gid with no matching entry in /etc/group on the machine running fpm. Typical with tarballs created on another host or inside a minimal Docker/CI image that lacks the site-specific group.","commonSituations":"CI containers or chroots with a trimmed /etc/group; source tarballs whose files were chgrp'd to LDAP/NIS-managed groups not resolvable in the build sandbox; gids reused from a different machine.","solutions":["Create the missing group on the build host before running fpm: `getent group <gid> || groupadd -g <gid> <name>`","Run fpm in an environment that shares the group database of the system that produced the input files","chgrp the input tree to a group that exists on the build host, then rebuild","Accept the numeric-gid fallback and verify the target puppet nodes have a group with that numeric gid"],"exampleFix":"# before: gid 12345 exists only on the original build host\nfpm -s dir -t puppet -n myapp -v 1.0 ./pkg/\n\n# after: make the gid resolvable where fpm runs\ngetent group 12345 || sudo groupadd -g 12345 appgrp\nfpm -s dir -t puppet -n myapp -v 1.0 ./pkg/","handlingStrategy":"validation","validationCode":"# Scan the tree you will hand to fpm for gids unresolvable on this host\nrequire 'etc'\nunresolved = Dir.glob('pkg/**/*').map { |f| File.lstat(f).gid }.uniq.reject do |gid|\n  begin\n    Etc.getgrgid(gid)\n    false\n  rescue ArgumentError\n    true\n  end\nend\nabort \"unresolvable gids: #{unresolved.join(', ')}\" unless unresolved.empty?","typeGuard":"def group_resolvable?(gid)\n  Etc.getgrgid(gid)\n  true\nrescue ArgumentError\n  false\nend","tryCatchPattern":"begin\n  name = Etc.getgrgid(gid).name\nrescue ArgumentError\n  logger.warn(\"gid #{gid} has no group entry; using numeric fallback\")\n  name = gid.to_s\nend","preventionTips":["Run fpm in an image that shares /etc/group with the system that produced the input files","chgrp input trees to a group that exists on the build host before invoking fpm","In CI, assert `getent group <gid>` succeeds for every gid your artifacts carry"],"tags":["puppet","gid","etc-getgrgid","group-lookup","manifest"],"backgroundTag":"user-group-lookup-failure","analyzedSha":"b6d77ba72a560b687723376a0e5115c3a92634ad","analyzedAt":"2026-08-21T16:39:02.570Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}