{"record":{"id":"15d2585f29bcf717","repo":"puppetlabs/puppet","slug":"could-not-open-selinux-category-translation-file","errorCode":null,"errorMessage":"Could not open SELinux category translation file %{path}.","messagePattern":"Could not open SELinux category translation file %(.+?)\\.","errorType":"exception","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/selinux.rb","lineNumber":206,"sourceCode":"    # We don't cache this, but there's already a ton of duplicate work\n    # in the selinux handling code.\n\n    path = Selinux.selinux_translations_path\n    begin\n      File.open(path).each do |line|\n        line.strip!\n        next if line.empty?\n        next if line[0] == \"#\" # skip comments\n\n        line.gsub!(/[[:space:]]+/m, '')\n        mapping = line.split(\"=\", 2)\n        if category == mapping[1]\n          return mapping[0]\n        end\n      end\n    rescue SystemCallError => ex\n      log_exception(ex)\n      raise Puppet::Error, _(\"Could not open SELinux category translation file %{path}.\") % { context: context }\n    end\n\n    category\n  end\n\n  ########################################################################\n  # Internal helper methods from here on in, kids.  Don't fiddle.\n  private\n\n  # Check filesystem a path resides on for SELinux support against\n  # whitelist of known-good filesystems.\n  # Returns true if the filesystem can support SELinux labels and\n  # false if not.\n  def selinux_label_support?(file)\n    fstype = find_fs(file)\n    return false if fstype.nil?\n\n    filesystems = %w[ext2 ext3 ext4 gfs gfs2 xfs jfs btrfs tmpfs zfs]","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/selinux.rb#L188-L224","documentation":"selinux_category_to_label (selinux.rb:187-207) opens the SELinux category translation file at Selinux.selinux_translations_path (setrans.conf) to map a category like 'SystemLow' to its numeric label (e.g., 's0'). If opening/reading raises SystemCallError (ENOENT, EACCES), it logs the exception and raises Puppet::Error 'Could not open SELinux category translation file %{path}.'. Ground-truth caveat in this source: the format string uses %{path} but the hash supplies { context: context } (selinux.rb:206), and `context` is not even in scope (the parameter is `category`), so the rescue path actually dies with NameError/KeyError before producing the intended Puppet::Error on this Puppet version.","triggerScenarios":"Managing SELinux categories/ranges (selrange) on a host where /etc/selinux/<policy>/setrans.conf is missing (policycoreutils / selinux-policy not installed) or unreadable (wrong ownership, EACCES under a confined puppet agent); containers with SELinux tooling stripped out.","commonSituations":"Minimal RHEL/CentOS images without the selinux-policy package; containers where /etc/selinux is an empty mount; MCS category management (svirt, docker selinux labels) on hosts whose translations file was removed during hardening.","solutions":["Install/restore the translation file: ensure the selinux-policy and policycoreutils packages are present and /etc/selinux/$(selinuxconfig -p)/setrans.conf exists.","Fix permissions/ownership so the puppet user can read the file.","Pre-check File.readable?(Selinux.selinux_translations_path) before invoking category handling and skip selrange management when absent.","Upgrade Puppet: the rescue branch references an undefined `context` instead of `path`, so on this version the failure mode is a NameError/KeyError rather than the intended Puppet::Error."],"exampleFix":"// before\nlabel = selinux_category_to_label('SystemLow') # setrans.conf missing -> rescue path -> NameError\n\n// after\npath = Selinux.selinux_translations_path\nunless path && File.readable?(path)\n  Puppet.debug(\"skipping category translation; #{path} unreadable\")\n  return nil\nend\nlabel = selinux_category_to_label('SystemLow')","handlingStrategy":"validation","validationCode":"path = defined?(Selinux) ? Selinux.selinux_translations_path : nil\ntranslatable = path.is_a?(String) && File.readable?(path)\nreturn default unless translatable","typeGuard":null,"tryCatchPattern":"begin\n  selinux_category_to_label(category)\nrescue Puppet::Error, NameError, KeyError => e\n  Puppet.err(\"SELinux translation file unavailable: #{e.message}\")\n  category\nend","preventionTips":["Check File.readable?(Selinux.selinux_translations_path) before selrange management.","Keep selinux-policy/policycoreutils installed on SELinux-enabled nodes in your base image.","On this puppet version the rescue branch itself is broken (%{path} vs undefined `context`); expect NameError and plan the upgrade."],"tags":["selinux","linux","puppet","file-access","config-missing"],"backgroundTag":"selinux-config-missing","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}