puppetlabs/puppet · error · Puppet::Util::Windows::Error
out_buffer is required
Error message
out_buffer is required
What it means
Puppet::Util::Windows::File.device_io_control raises Puppet::Util::Windows::Error('out_buffer is required') when called with out_buffer nil - DeviceIoControl always needs a destination for returned bytes, so this is a programmer error at the call site, not a system failure. No Win32 call has been made yet when it raises.
Source
Thrown at lib/puppet/util/windows/file.rb:183
end
def self.get_reparse_point_tag(handle)
reparse_tag = nil
# 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)
# DWORD ReparseTag is the first member of the struct
reparse_tag = reparse_data_buffer_ptr.read_win32_ulong
end
reparse_tag
end
def self.device_io_control(handle, io_control_code, in_buffer = nil, out_buffer = nil)
if out_buffer.nil?
raise Puppet::Util::Windows::Error, _("out_buffer is required")
end
FFI::MemoryPointer.new(:dword, 1) do |bytes_returned_ptr|
result = DeviceIoControl(
handle,
io_control_code,
in_buffer, in_buffer.nil? ? 0 : in_buffer.size,
out_buffer, out_buffer.size,
bytes_returned_ptr,
nil
)
if result == FFI::WIN32_FALSE
raise Puppet::Util::Windows::Error, "DeviceIoControl(#{handle}, #{io_control_code}, " \
"#{in_buffer}, #{in_buffer ? in_buffer.size : ''}, " \
"#{out_buffer}, #{out_buffer ? out_buffer.size : ''}"
end
endView on GitHub (pinned to e227c27540)
Solutions
- Always pass an out_buffer, e.g. FFI::MemoryPointer.new(MAXIMUM_REPARSE_DATA_BUFFER_SIZE) (>= 10240 bytes for reparse data)
- Read returned byte counts from the API result/overlapped struct rather than inferring from buffer size
- Treat this raise as a defect signal in your own wrapper - fix the call, do not rescue it
Example fix
// before Puppet::Util::Windows::File.device_io_control(handle, FSCTL_GET_REPARSE_POINT, nil) # nil out_buffer // after FFI::MemoryPointer.new(10240) do |out| Puppet::Util::Windows::File.device_io_control(handle, FSCTL_GET_REPARSE_POINT, nil, out) end
Defensive patterns
Strategy: validation
Validate before calling
raise ArgumentError, 'device_io_control requires out_buffer' if out_buffer.nil? out_buffer ||= FFI::MemoryPointer.new(Puppet::Util::Windows::File::MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
Try / catch
begin
Puppet::Util::Windows::File.device_io_control(handle, code, in_buffer, out_buffer)
rescue Puppet::Util::Windows::Error => e
raise unless e.message.include?('out_buffer is required')
raise ArgumentError, 'fix call site: out_buffer is mandatory'
end Prevention
- Always allocate an output buffer; for reparse data it must be >= 10240 bytes
- Treat this raise as a bug in the caller - never swallow it
- Wrap device_io_control once in your own helper that enforces the buffer contract
When it happens
Trigger: Calling device_io_control(handle, code, in_buffer) with only three arguments (out_buffer defaults to nil), or explicitly passing nil while intending an in-place buffer. Typical when adapting sample code for codes that only write output (e.g. FSCTL_GET_REPARSE_POINT).
Common situations: First-time FFI wrappers around DeviceIoControl assuming output is optional; refactors that dropped the fourth argument; copy-paste from in-buffer-only IOCTL examples.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- DeviceIoControl(#{handle}, #{io_control_code}, #{in_buffer},
- RegisterEventSourceW failed to open Windows eventlog
- ReportEventW failed to report event to Windows eventlog
- Failed to get computer name
- Failed to get user name
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/fccbd967756b5338.
Report an issue: GitHub.