puppetlabs/puppet · error · Puppet::Util::Windows::Error
Failed to open '%{path}'
Error message
Failed to open '%{path}' What it means
Raised by open_file when CreateFileW returns INVALID_HANDLE_VALUE. The file or directory is opened with OPEN_EXISTING plus FILE_FLAG_OPEN_REPARSE_POINT and FILE_FLAG_BACKUP_SEMANTICS, so the call fails outright when the path does not exist, access is denied, or the path cannot be opened in the requested mode. The appended Win32 message (via Puppet::Util::Windows::Error using FFI.errno) tells you which case it is, e.g. 'The system cannot find the file specified' or 'Access is denied'.
Source
Thrown at lib/puppet/util/windows/security.rb:525
dacl
end
# Open an existing file with the specified access mode, and execute a
# block with the opened file HANDLE.
def open_file(path, access, &block)
handle = CreateFileW(
wide_string(path),
access,
FILE::FILE_SHARE_READ | FILE::FILE_SHARE_WRITE,
FFI::Pointer::NULL, # security_attributes
FILE::OPEN_EXISTING,
FILE::FILE_FLAG_OPEN_REPARSE_POINT | FILE::FILE_FLAG_BACKUP_SEMANTICS,
FFI::Pointer::NULL_HANDLE
) # template
if handle == Puppet::Util::Windows::File::INVALID_HANDLE_VALUE
raise Puppet::Util::Windows::Error, _("Failed to open '%{path}'") % { path: path }
end
begin
yield handle
ensure
FFI::WIN32.CloseHandle(handle) if handle
end
# handle has already had CloseHandle called against it, nothing to return
nil
end
# Execute a block with the specified privilege enabled
def with_privilege(privilege, &block)
set_privilege(privilege, true)
yield
ensure
set_privilege(privilege, false)View on GitHub (pinned to e227c27540)
Solutions
- Check the appended Win32 text / e.code: 2 = file not found, 5 = access denied, 32 = sharing violation
- Verify the path exists at run time (File.exist?) before touching security on it
- Run the agent elevated (Administrator) or grant the agent account READ_CONTROL/WRITE_DAC on the target
- For long paths, use an absolute path with the \\?\\ prefix or shorten the directory tree
Example fix
// before
Puppet::Util::Windows::Security.get_security_descriptor(path)
# after
unless File.exist?(path)
raise Puppet::Error, "Cannot manage ACL: #{path} does not exist"
end
Puppet::Util::Windows::Security.get_security_descriptor(path) Defensive patterns
Strategy: validation
Validate before calling
raise Puppet::Error, "#{path} does not exist" unless File.exist?(path)
# ensure the agent can open it for security reads
accessible = File.readable?(path) rescue false Try / catch
begin
Puppet::Util::Windows::Security.get_security_descriptor(path)
rescue Puppet::Util::Windows::Error => e
case e.code
when 2 then Puppet.err "#{path} vanished mid-run"
when 5 then Puppet.err "#{path}: no access; run agent elevated"
when 32 then Puppet.err "#{path}: sharing violation; retry later"
end
raise
end Prevention
- Check File.exist? immediately before touching security, not at compile time
- Run the agent elevated when managing system-owned paths
- Handle code 2 (not found) and 5 (access denied) distinctly; they need different fixes
When it happens
Trigger: get_security_descriptor or set_security_descriptor on a path that was deleted between catalog compile and run, a path the agent account cannot open (no READ_CONTROL for reads, no WRITE_DAC/WRITE_OWNER for writes), an invalid/overlong path, or a file exclusively locked with no share flags.
Common situations: Puppet managing a file that another process removes/recreates mid-run; running the agent as a limited user against system-owned files; paths longer than MAX_PATH; antivirus temporarily locking targets.
Related errors
- Invalid DACL
- Failed to adjust process privileges
- Failed to get security information
- Failed to get security descriptor control
- Failed to initialize ACL
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/cbdaef3099fb3924.
Report an issue: GitHub.