puppetlabs/puppet · error · Puppet::Util::Windows::Error
Failed to set file attributes
Error message
Failed to set file attributes
What it means
Puppet::Util::Windows::File.set_attributes calls SetFileAttributesW and raises Puppet::Util::Windows::Error when it returns FALSE. It is used by add_attributes/remove_attributes (e.g. toggling FILE_ATTRIBUTE_READONLY around file operations). The appended Win32 message and e.code give the cause: invalid path, access denied, or the file being locked in an incompatible state.
Source
Thrown at lib/puppet/util/windows/file.rb:120
if (oldattrs | flags) != oldattrs
set_attributes(path, oldattrs | flags)
end
end
module_function :add_attributes
def remove_attributes(path, flags)
oldattrs = get_attributes(path)
if (oldattrs & ~flags) != oldattrs
set_attributes(path, oldattrs & ~flags)
end
end
module_function :remove_attributes
def set_attributes(path, flags)
success = SetFileAttributesW(wide_string(path), flags) != FFI::WIN32_FALSE
raise Puppet::Util::Windows::Error, _("Failed to set file attributes") unless success
success
end
module_function :set_attributes
# define INVALID_HANDLE_VALUE ((HANDLE)(LONG_PTR)-1)
INVALID_HANDLE_VALUE = FFI::Pointer.new(-1).address
def self.create_file(file_name, desired_access, share_mode, security_attributes,
creation_disposition, flags_and_attributes, template_file_handle)
result = CreateFileW(wide_string(file_name.to_s),
desired_access, share_mode, security_attributes, creation_disposition,
flags_and_attributes, template_file_handle)
return result unless result == INVALID_HANDLE_VALUE
raise Puppet::Util::Windows::Error, "CreateFile(#{file_name}, #{desired_access.to_s(8)}, #{share_mode.to_s(8)}, " \
"#{security_attributes}, #{creation_disposition.to_s(8)}, " \View on GitHub (pinned to e227c27540)
Solutions
- Confirm the file still exists at the moment of the call (get_attributes(path, false))
- Map e.code: 5 = elevate or fix ACLs, 32 = retry after the lock clears, 2/3 = fix the path
- Sequence operations so attributes are changed immediately before the dependent action, minimizing the race window
- Schedule AV exclusions for managed directories if code 32 recurs
Example fix
// before Puppet::Util::Windows::File.set_attributes(path, new_flags) // after begin Puppet::Util::Windows::File.set_attributes(path, new_flags) rescue Puppet::Util::Windows::Error => e retry if e.code == 32 && (retry_count += 1) < 3 raise end
Defensive patterns
Strategy: try-catch
Validate before calling
exists = Puppet::Util::Windows::File.get_attributes(path, false) != Puppet::Util::Windows::File::INVALID_FILE_ATTRIBUTES
raise ArgumentError, "#{path} gone" unless exists Try / catch
begin Puppet::Util::Windows::File.set_attributes(path, flags) rescue Puppet::Util::Windows::Error => e retry if e.code == 32 && (tries ||= 0) < 3 # sharing violation is transient raise end
Prevention
- Change attributes immediately before the dependent delete/replace to shrink the race window
- Do not retry code 5 (access denied) - fix rights or elevation instead
- Add AV exclusions for managed trees if attribute flips keep hitting locks
When it happens
Trigger: set_attributes(path, flags) when the path no longer exists (2/3), the caller cannot write the file's metadata (5), or another handle has the file open with sharing restrictions (32). Also triggered by passing a combined flags value where some bits conflict with the file's current state.
Common situations: Puppet clearing the read-only bit before deleting or replacing a file while antivirus or a backup job holds it; files on read-only network shares; non-admin agents touching system files; files already deleted by a previous resource in the same run.
Related errors
- GetFileAttributes(#{file_name})
- 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/dcf633c0a8a9813f.
Report an issue: GitHub.