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

Failed to fetch services

Error message

Failed to fetch services

What it means

Raised by services (the enumerator) when EnumServicesStatusExW returns FALSE while paging through all services of all states. The call runs with a 30KB-ish buffer and retries with the required size, so residual failures are usually environmental: SCM access denied, the service database locked, or the RPC endpoint unavailable. The appended Win32 text names the cause.

Source

Thrown at lib/puppet/util/windows/service.rb:258

              )
              size_required = bytes_pointer.read_dword
              FFI::MemoryPointer.new(size_required) do |buffer_ptr|
                resume_ptr.write_dword(0)
                svcs_ret_ptr.write_dword(0)
                success = EnumServicesStatusExW(
                  scm,
                  :SC_ENUM_PROCESS_INFO,
                  ALL_SERVICE_TYPES,
                  SERVICE_STATE_ALL,
                  buffer_ptr,
                  buffer_ptr.size,
                  bytes_pointer,
                  svcs_ret_ptr,
                  resume_ptr,
                  FFI::Pointer::NULL
                )
                if success == FFI::WIN32_FALSE
                  raise Puppet::Util::Windows::Error, _("Failed to fetch services")
                end

                # Now that the buffer is populated with services
                # we pull the data from memory using pointer arithmetic:
                # the number of services returned by the function is
                # available to be read from svcs_ret_ptr, and we iterate
                # that many times moving the cursor pointer the length of
                # ENUM_SERVICE_STATUS_PROCESSW.size. This should iterate
                # over the buffer and extract each struct.
                services_returned = svcs_ret_ptr.read_dword
                cursor_ptr = FFI::Pointer.new(ENUM_SERVICE_STATUS_PROCESSW, buffer_ptr)
                0.upto(services_returned - 1) do |index|
                  service = ENUM_SERVICE_STATUS_PROCESSW.new(cursor_ptr[index])
                  services[service[:lpServiceName].read_arbitrary_wide_string_up_to(SERVICENAME_MAX)] = {
                    :display_name => service[:lpDisplayName].read_arbitrary_wide_string_up_to(SERVICENAME_MAX),
                    :service_status_process => service[:ServiceStatusProcess]
                  }
                end

View on GitHub (pinned to e227c27540)

Solutions

  1. Read e.code: 5 = access denied, 1071 = service database locked, 1717 = RPC server unavailable
  2. Retry the enumeration after a short wait when the box is mid-update
  3. Run elevated so the SCM handle carries enumeration rights
  4. If RpcSs is failing, check its health (sc query rpcss) before retrying
Defensive patterns

Strategy: retry

Try / catch

def list_services(tries: 3)
  Puppet::Util::Windows::Service.services
rescue Puppet::Util::Windows::Error => e
  retry if (tries -= 1) > 0 && [5, 1071, 1717, 1722].include?(e.code) # denied/locked/RPC
  raise
end

Prevention

When it happens

Trigger: Calling Puppet::Util::Windows::Service.services on a machine where the SCM denies SC_MANAGER_ENUMERATE_SERVICE, during concurrent service installation/uninstallation (database locked), or when the RPC server (RpcSs) is not healthy.

Common situations: Service discovery at the start of a Puppet run colliding with MSI installers or updates installing services; hardened boxes restricting SCM enumeration; boot-time runs before the SCM is fully ready.

Related errors


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