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

GetVersionEx failed

Error message

GetVersionEx failed

What it means

Raised by Process.windows_major_version (lib/puppet/util/windows/process.rb:283) when GetVersionExW returns FALSE after dwOSVersionInfoSize is set on the OSVERSIONINFO struct. Genuine failures are nearly nonexistent; the realistic cause is an OSVERSIONINFO FFI layout/size mismatch (a Puppet regression after struct changes), since the size field is what makes this API fail. Separately, GetVersionEx is deprecated and under-reports version on Windows 8.1+ without a compatibility manifest.

Source

Thrown at lib/puppet/util/windows/process.rb:283

    rescue Puppet::Util::Windows::Error => e
      raise e if e.code != ERROR_NO_SUCH_PRIVILEGE
    ensure
      FFI::WIN32.CloseHandle(handle) if handle
    end
  end
  module_function :elevated_security?

  def windows_major_version
    ver = 0

    FFI::MemoryPointer.new(OSVERSIONINFO.size) do |os_version_ptr|
      os_version = OSVERSIONINFO.new(os_version_ptr)
      os_version[:dwOSVersionInfoSize] = OSVERSIONINFO.size

      result = GetVersionExW(os_version_ptr)

      if result == FFI::WIN32_FALSE
        raise Puppet::Util::Windows::Error, _("GetVersionEx failed")
      end

      ver = os_version[:dwMajorVersion]
    end

    ver
  end
  module_function :windows_major_version

  # Returns a hash of the current environment variables encoded as UTF-8
  # The memory block returned from GetEnvironmentStringsW is double-null terminated and the vars are paired as below;
  # Var1=Value1\0
  # Var2=Value2\0
  # VarX=ValueX\0\0
  # Note - Some env variable names start with '=' and are excluded from the return value
  # Note - The env_ptr MUST be freed using the FreeEnvironmentStringsW function
  # Note - There is no technical limitation to the size of the environment block returned.
  #   However a practical limit of 64K is used as no single environment variable can exceed 32KB

View on GitHub (pinned to e227c27540)

Solutions

  1. Treat as a Puppet bug signal: move to a Puppet release where the OSVERSIONINFO layout is correct (update or rollback).
  2. Catch Puppet::Util::Windows::Error and fall back to another version source: Facter os.release, RtlGetVersion, or the output of cmd /c ver.
  3. Do not use windows_major_version for fine-grained OS gating on Windows 8.1+ — prefer Facter facts or feature detection.

Example fix

# before
major = Process.windows_major_version

# after — fall back to Facter
begin
  major = Process.windows_major_version
rescue Puppet::Util::Windows::Error
  major = Facter.value(:os)[:release].to_s.split('.').first.to_i
end
Defensive patterns

Strategy: fallback

Try / catch

begin
  major = Process.windows_major_version
rescue Puppet::Util::Windows::Error => e
  Puppet.debug "windows_major_version failed (#{e.code}); using Facter"
  major = Facter.value(:os)[:release].to_s.split('.').first.to_i
end

Prevention

When it happens

Trigger: FFI struct layout for OSVERSIONINFO diverging from the SDK so GetVersionExW rejects the size; unusual compatibility shims. Overwhelmingly a packaging/regression signal rather than an environment problem.

Common situations: A Puppet upgrade changing the FFI struct definitions; running under compatibility layers; virtually never observed on stock systems.

Related errors


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