puppetlabs/puppet · error · Puppet::Util::Windows::Error
CreateFile(#{file_name}, #{desired_access.to_s(8)}, #{share_
Error message
CreateFile(#{file_name}, #{desired_access.to_s(8)}, #{share_mode.to_s(8)}, #{security_attributes}, #{creation_disposition.to_s(8)}, #{flags_and_attributes.to_s(8)}, #{template_file_handle}) What it means
Puppet::Util::Windows::File.create_file wraps CreateFileW and raises Puppet::Util::Windows::Error when the returned handle equals INVALID_HANDLE_VALUE. The message dumps every argument (access, share mode, security attributes, disposition, flags - most in octal) so you can reproduce the exact open. e.code carries the Win32 reason: not-found, access denied, sharing violation, or invalid parameter combination.
Source
Thrown at lib/puppet/util/windows/file.rb:137
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)}, " \
"#{flags_and_attributes.to_s(8)}, #{template_file_handle})"
end
def self.get_reparse_point_data(handle, &block)
# must be multiple of 1024, min 10240
FFI::MemoryPointer.new(MAXIMUM_REPARSE_DATA_BUFFER_SIZE) do |reparse_data_buffer_ptr|
device_io_control(handle, FSCTL_GET_REPARSE_POINT, nil, reparse_data_buffer_ptr)
reparse_tag = reparse_data_buffer_ptr.read_win32_ulong
buffer_type = case reparse_tag
when IO_REPARSE_TAG_SYMLINK
SYMLINK_REPARSE_DATA_BUFFER
when IO_REPARSE_TAG_MOUNT_POINT
MOUNT_POINT_REPARSE_DATA_BUFFER
when IO_REPARSE_TAG_NFS
raise Puppet::Util::Windows::Error, "Retrieving NFS reparse point data is unsupported"
elseView on GitHub (pinned to e227c27540)
Solutions
- Decode e.code first: 2/3 path, 5 rights, 32 lock, 87 bad flag/disposition combo
- Ensure the disposition matches reality (CREATE_ALWAYS vs OPEN_EXISTING)
- Match share_mode with how other holders opened the file, or wait for the lock
- Run elevated for system files; enable long-path support (gpedit/registry LongPathsEnabled) for deep paths
Example fix
// before
handle = Puppet::Util::Windows::File.create_file(path, GENERIC_READ, 0, nil, OPEN_EXISTING, 0, 0)
// after
begin
handle = Puppet::Util::Windows::File.create_file(path, GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, 0, 0)
rescue Puppet::Util::Windows::Error => e
raise Puppet::Error, "cannot open #{path}: win32 code #{e.code}"
end Defensive patterns
Strategy: try-catch
Validate before calling
raise ArgumentError, 'path missing' unless File.exist?(path) share_mode ||= Puppet::FFI::Windows::Constants::FILE_SHARE_READ | Puppet::FFI::Windows::Constants::FILE_SHARE_WRITE
Try / catch
begin
handle = Puppet::Util::Windows::File.create_file(path, desired_access, share_mode, security_attributes,
creation_disposition, flags_and_attributes, template_file_handle)
rescue Puppet::Util::Windows::Error => e
raise "#{path}: not found" if [2, 3].include?(e.code)
raise "#{path}: access denied" if e.code == 5
raise "#{path}: locked by another process" if e.code == 32
raise
end Prevention
- Open with FILE_FLAG_OPEN_REPARSE_POINT when inspecting symlinks
- Include FILE_SHARE_READ|FILE_SHARE_WRITE in share_mode unless exclusivity is required
- Enable Windows long-path support for deep directory trees
When it happens
Trigger: Opening a nonexistent path (2/3) with an OPEN_EXISTING-style disposition; requesting GENERIC_WRITE on admin-owned files unelevated (5); opening a file another process holds without a compatible share_mode (32); passing mutually exclusive creation_disposition/flags_and_attributes; opening a symlink without FILE_FLAG_OPEN_REPARSE_POINT; paths beyond MAX_PATH without long-path enablement.
Common situations: Puppet opening files for content replacement under Program Files as a filtered token; reparse-point inspection (this wrapper feeds get_reparse_point_data) where the link was removed between stat and open; backup software holding exclusive locks; long nested module paths exceeding 260 characters.
Related errors
- ReplaceFile(#{target}, #{source})
- MoveFileEx(#{source}, #{target}, #{flags.to_s(8)})
- GetFileAttributes(#{file_name})
- Failed to set file attributes
- Failed to call GetLongPathName
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/e326cedad2cf4774.
Report an issue: GitHub.