{"record":{"id":"527e4576c64d28c8","repo":"puppetlabs/puppet","slug":"getversionex-failed","errorCode":null,"errorMessage":"GetVersionEx failed","messagePattern":"GetVersionEx failed","errorType":"exception","errorClass":"Puppet::Util::Windows::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/windows/process.rb","lineNumber":283,"sourceCode":"    rescue Puppet::Util::Windows::Error => e\n      raise e if e.code != ERROR_NO_SUCH_PRIVILEGE\n    ensure\n      FFI::WIN32.CloseHandle(handle) if handle\n    end\n  end\n  module_function :elevated_security?\n\n  def windows_major_version\n    ver = 0\n\n    FFI::MemoryPointer.new(OSVERSIONINFO.size) do |os_version_ptr|\n      os_version = OSVERSIONINFO.new(os_version_ptr)\n      os_version[:dwOSVersionInfoSize] = OSVERSIONINFO.size\n\n      result = GetVersionExW(os_version_ptr)\n\n      if result == FFI::WIN32_FALSE\n        raise Puppet::Util::Windows::Error, _(\"GetVersionEx failed\")\n      end\n\n      ver = os_version[:dwMajorVersion]\n    end\n\n    ver\n  end\n  module_function :windows_major_version\n\n  # Returns a hash of the current environment variables encoded as UTF-8\n  # The memory block returned from GetEnvironmentStringsW is double-null terminated and the vars are paired as below;\n  # Var1=Value1\\0\n  # Var2=Value2\\0\n  # VarX=ValueX\\0\\0\n  # Note - Some env variable names start with '=' and are excluded from the return value\n  # Note - The env_ptr MUST be freed using the FreeEnvironmentStringsW function\n  # Note - There is no technical limitation to the size of the environment block returned.\n  #   However a practical limit of 64K is used as no single environment variable can exceed 32KB","sourceCodeStart":265,"sourceCodeEnd":301,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/windows/process.rb#L265-L301","documentation":"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.","triggerScenarios":"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.","commonSituations":"A Puppet upgrade changing the FFI struct definitions; running under compatibility layers; virtually never observed on stock systems.","solutions":["Treat as a Puppet bug signal: move to a Puppet release where the OSVERSIONINFO layout is correct (update or rollback).","Catch Puppet::Util::Windows::Error and fall back to another version source: Facter os.release, RtlGetVersion, or the output of cmd /c ver.","Do not use windows_major_version for fine-grained OS gating on Windows 8.1+ — prefer Facter facts or feature detection."],"exampleFix":"# before\nmajor = Process.windows_major_version\n\n# after — fall back to Facter\nbegin\n  major = Process.windows_major_version\nrescue Puppet::Util::Windows::Error\n  major = Facter.value(:os)[:release].to_s.split('.').first.to_i\nend","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"begin\n  major = Process.windows_major_version\nrescue Puppet::Util::Windows::Error => e\n  Puppet.debug \"windows_major_version failed (#{e.code}); using Facter\"\n  major = Facter.value(:os)[:release].to_s.split('.').first.to_i\nend","preventionTips":["Prefer Facter os facts over GetVersionEx-derived values","Pin known-good Puppet versions on Windows hosts","Never gate behavior on exact major version alone — use feature detection"],"tags":["windows","win32-api","os-version","deprecated-api","ffi","puppet"],"backgroundTag":"win32-os-version-query-failed","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}