puppetlabs/puppet · error · Puppet::Util::Windows::Error
GetFileAttributes(#{file_name})
Error message
GetFileAttributes(#{file_name}) What it means
Puppet::Util::Windows::File.get_attributes queries GetFileAttributesW and raises Puppet::Util::Windows::Error when the API returns INVALID_FILE_ATTRIBUTES (0xFFFFFFFF). That sentinel means the path could not be queried - typically nonexistent path or access denied on some parent - so e.code is the discriminator. The method has an escape hatch: pass raise_on_invalid=false to get the raw sentinel back instead of an exception.
Source
Thrown at lib/puppet/util/windows/file.rb:93
reparse_point = (result & FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT
if reparse_point && symlink_reparse_point?(path)
# walk the symlink and try again...
seen_paths << path.downcase
path = readlink(path)
else
# file was found and its not a symlink
return true
end
end
false
end
module_function :exist?
def get_attributes(file_name, raise_on_invalid = true)
result = GetFileAttributesW(wide_string(file_name.to_s))
if raise_on_invalid && result == INVALID_FILE_ATTRIBUTES
raise Puppet::Util::Windows::Error, "GetFileAttributes(#{file_name})"
end
result
end
module_function :get_attributes
def add_attributes(path, flags)
oldattrs = get_attributes(path)
if (oldattrs | flags) != oldattrs
set_attributes(path, oldattrs | flags)
end
end
module_function :add_attributes
def remove_attributes(path, flags)
oldattrs = get_attributes(path)
View on GitHub (pinned to e227c27540)
Solutions
- Verify the path spelling/existence first (File.exist?) when a miss is expected
- Pass raise_on_invalid: false and compare the result to INVALID_FILE_ATTRIBUTES yourself
- Inspect e.code: 5 means access denied (fix ACLs/elevation), 2/3 means missing (fix the path)
- For repeated probes on protected trees, run elevated or relax the parent-folder ACL
Example fix
// before attrs = Puppet::Util::Windows::File.get_attributes(path) # raises if missing // after attrs = Puppet::Util::Windows::File.get_attributes(path, false) missing = attrs == Puppet::Util::Windows::File::INVALID_FILE_ATTRIBUTES
Defensive patterns
Strategy: fallback
Validate before calling
attrs = Puppet::Util::Windows::File.get_attributes(path, false)
if attrs == Puppet::Util::Windows::File::INVALID_FILE_ATTRIBUTES
# missing OR access-denied - distinguish before deciding
Puppet.debug("cannot query attributes for #{path}")
end Try / catch
begin attrs = Puppet::Util::Windows::File.get_attributes(path) rescue Puppet::Util::Windows::Error => e raise unless [2, 3, 5].include?(e.code) attrs = nil # treat as absent/inaccessible end
Prevention
- Pass raise_on_invalid: false when probing - it is the documented escape hatch
- Remember INVALID_FILE_ATTRIBUTES conflates 'missing' with 'access denied'
- Validate UNC and drive-letter spellings before querying system paths
When it happens
Trigger: get_attributes(path) with the default raise_on_invalid=true on a path that does not exist (2/3), a path whose parent directory denies traversal (5), a malformed UNC (\\server\share\...) or drive letter, or a file being deleted concurrently between an existence check and the query.
Common situations: Probing for files under locked-down directories (e.g. other users' profiles) where even attribute queries are denied; race with uninstallers deleting files mid-run; typos in configured paths; tools that assume error == not-found and mask access-denied as missing.
Related errors
- Failed to set file attributes
- ReplaceFile(#{target}, #{source})
- MoveFileEx(#{source}, #{target}, #{flags.to_s(8)})
- CreateFile(#{file_name}, #{desired_access.to_s(8)}, #{share_
- Failed to call GetLongPathName
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/04fea4d4ff8a4a97.
Report an issue: GitHub.