puppetlabs/puppet · error · Puppet::Util::Windows::Error

ReportEventW failed to report event to Windows eventlog

Error message

ReportEventW failed to report event to Windows eventlog

What it means

EventLog#report_event raises EventLogError (carrying FFI.errno) when the ReportEventW API call returns FALSE — the write to the Windows event log failed. The handle comes from RegisterEventSourceW at construction, and #close nils @eventlog_handle, so the most common cause is reporting on a stale/closed handle or the log service becoming unavailable mid-run.

Source

Thrown at lib/puppet/util/windows/eventlog.rb:79

    unless args[:data].is_a?(String)
      raise ArgumentError, _("data must be a string, not %{class_name}") % { class_name: args[:data].class }
    end

    from_string_to_wide_string(args[:data]) do |message_ptr|
      FFI::MemoryPointer.new(:pointer) do |message_array_ptr|
        message_array_ptr.write_pointer(message_ptr)
        user_sid = FFI::Pointer::NULL
        raw_data = FFI::Pointer::NULL
        raw_data_size = 0
        num_strings = 1
        eventlog_category = 0
        report_result = ReportEventW(@eventlog_handle, args[:event_type],
                                     eventlog_category, args[:event_id], user_sid,
                                     num_strings, raw_data_size, message_array_ptr, raw_data)

        if report_result == WIN32_FALSE
          # TRANSLATORS 'Windows' is the operating system and 'ReportEventW' is a API call and should not be translated
          raise EventLogError.new(_("ReportEventW failed to report event to Windows eventlog"), FFI.errno)
        end
      end
    end
  end

  class << self
    # Feels more natural to do Puppet::Util::Window::EventLog.open("MyApplication")
    alias :open :new

    # Query event identifier info for a given log level
    # @param level [Symbol] an event log level
    # @return [Array] Win API Event ID, Puppet Event ID
    # @api public
    def to_native(level)
      case level
      when :debug, :info, :notice
        [EVENTLOG_INFORMATION_TYPE, 0x01]
      when :warning

View on GitHub (pinned to e227c27540)

Solutions

  1. Create a fresh EventLog instance (EventLog.open/new) per reporting batch instead of caching one forever
  2. Never call report_event after close — reopen when logging is needed again
  3. Always derive event_type/event_id via Puppet::Util::Windows::EventLog.to_native(level)
  4. Check FFI.errno on the raised error (e.g. ERROR_INVALID_HANDLE confirms a stale handle)

Example fix

# before
log = Puppet::Util::Windows::EventLog.open('Puppet')
log.close
log.report_event(data: 'msg', event_type: t, event_id: i)  # stale handle -> EventLogError

# after
log = Puppet::Util::Windows::EventLog.open('Puppet')
log.report_event(data: 'msg', event_type: t, event_id: i)
log.close
Defensive patterns

Strategy: try-catch

Try / catch

begin
  @log.report_event(data: msg, event_type: t, event_id: i)
rescue Puppet::Util::Windows::EventLogError
  @log = Puppet::Util::Windows::EventLog.new('Puppet') # reopen: handle may be stale
  @log.report_event(data: msg, event_type: t, event_id: i)
end

Prevention

When it happens

Trigger: Calling report_event on an instance after close has run (handle is nil); the Event Log service stopped or the log was cleared between open and write; passing event_type/event_id values not derived from EventLog.to_native so the API rejects the record.

Common situations: Long-running Ruby processes caching one EventLog instance across service restarts; logging during shutdown after the handle was closed; reusing an instance after an earlier failure.

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/9b4d7ab6736e439f. Report an issue: GitHub.