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 falseView on GitHub (pinned to e227c27540)
Solutions
- Run the Puppet agent as root (macOS password management requires it).
- Check and restore expected ownership/permissions: `ls -l /var/db/shadow/hash/` — files are typically 0400 root:wheel.
- Verify readability as root: `sudo head -c 4 /var/db/shadow/hash/<GUID>`.
- 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
- Run the Puppet agent as root on macOS.
- Do not harden /var/db/shadow/hash to exclude root; keep root:wheel 0400-style ownership.
- On modern macOS (10.7+), this path is legacy — avoid password inspection flows that hit it.
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
- Invalid #{field} given for user #{user_name}
- OS X 10.7 requires a Salted SHA512 hash password of 136 char
- OS X versions > 10.7 require a Salted SHA512 PBKDF2 password
- puppet.plans/invalid-name
- Could not read MessagePack data for %{indirection} %{key}: %
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/c5633d338c4da008.
Report an issue: GitHub.