puppetlabs/puppet · error · Puppet::Error

Could not read password hash file at #{password_hash_file}

Error message

Could not read password hash file at #{password_hash_file}

What it means

Raised by Puppet's macOS DirectoryService user provider when the OS X 10.5/10.6 password hash file (/var/db/shadow/hash/<GUID>) exists and is a regular file, but File.readable? returns false — the process lacks read permission on it. get_sha1 then refuses to read and raises instead of silently returning nil.

Source

Thrown at lib/puppet/provider/user/directoryservice.rb:237

      if value.nil?
        raise Puppet::Error, "Invalid #{field} given for user #{user_name}"
      end

      value.unpack1('H*')
    when 'iterations'
      Integer(embedded_binary_plist['SALTED-SHA512-PBKDF2'][field])
    else
      raise Puppet::Error, "Puppet has tried to read an incorrect value from the user #{user_name} in the SALTED-SHA512-PBKDF2 hash. Acceptable fields are 'salt', 'entropy', or 'iterations'."
    end
  end

  # In versions 10.5 and 10.6 of OS X, the password hash is stored in a file
  # in the /var/db/shadow/hash directory that matches the GUID of the user.
  def self.get_sha1(guid)
    password_hash = nil
    password_hash_file = "#{password_hash_dir}/#{guid}"
    if Puppet::FileSystem.exist?(password_hash_file) and File.file?(password_hash_file)
      raise Puppet::Error, "Could not read password hash file at #{password_hash_file}" unless File.readable?(password_hash_file)

      f = File.new(password_hash_file)
      password_hash = f.read
      f.close
    end
    password_hash
  end

  ##                   ##
  ## Ensurable Methods ##
  ##                   ##

  def exists?
    begin
      dscl '.', 'read', "/Users/#{@resource.name}"
    rescue Puppet::ExecutionFailure => e
      Puppet.debug("User was not found, dscl returned: #{e.inspect}")
      return false

View on GitHub (pinned to e227c27540)

Solutions

  1. Run the Puppet agent as root (macOS password management requires it).
  2. Check and restore expected ownership/permissions: `ls -l /var/db/shadow/hash/` — files are typically 0400 root:wheel.
  3. Verify readability as root: `sudo head -c 4 /var/db/shadow/hash/<GUID>`.
  4. If the hardening change was intentional, exclude these paths or stop managing passwords on those legacy systems.
Defensive patterns

Strategy: validation

Validate before calling

file = '/var/db/shadow/hash/<GUID>'
if File.exist?(file)
  File.readable?(file) or raise 'not readable - run agent as root'
end

Prevention

When it happens

Trigger: Reading/inspecting a 10.5–10.6 user's password hash when the agent runs as a non-root user, or the file's mode/ACL was tightened (these shadow files are normally root-only), or filesystem damage changed ownership.

Common situations: Puppet agent accidentally running as non-root; security hardening scripts that chmod 000 /var/db/shadow/hash/*; migrated volumes with wrong ownership.

Related errors


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