puppetlabs/puppet · error · Puppet::Error

Timed out while waiting for the pending transition from %{pe

Error message

Timed out while waiting for the pending transition from %{pending_state} to %{final_state} to finish. The current state is %{current_state}.

What it means

Raised by wait_on_pending_state when a service stays in a pending state (e.g. STOP_PENDING) without checkpoint progress for longer than the effective timeout. The timeout is the maximum of the caller's timeout and the service's advertised dwWaitHint (converted from milliseconds), and progress resets the timer, so this fires only when the service genuinely stalls. The message includes the pending state, the target final state, and the current state at timeout.

Source

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

            # the final_state OR if an unexpected transition
            # has occurred
            return if state == final_state
            unless state == pending_state
              raise Puppet::Error, _("Unexpected transition to the %{current_state} state while waiting for the pending transition from %{pending_state} to %{final_state} to finish.") % { current_state: SERVICE_STATES[state], pending_state: SERVICE_STATES[pending_state], final_state: SERVICE_STATES[final_state] }
            end

            # Check if any progress has been made since our last sleep
            # using the dwCheckPoint. If no progress has been made then
            # check if we've timed out, and raise an error if so
            if checkpoint > last_checkpoint
              elapsed_time = 0
              last_checkpoint = checkpoint
            else
              wait_hint = milliseconds_to_seconds(status[:dwWaitHint])
              timeout = wait_hint < timeout ? timeout : wait_hint

              if elapsed_time >= timeout
                raise Puppet::Error, _("Timed out while waiting for the pending transition from %{pending_state} to %{final_state} to finish. The current state is %{current_state}.") % { pending_state: SERVICE_STATES[pending_state], final_state: SERVICE_STATES[final_state], current_state: SERVICE_STATES[state] }
              end
            end
            wait_time = wait_hint_to_wait_time(wait_hint)
            # Wait a bit before rechecking the service's state
            sleep(wait_time)
            elapsed_time += wait_time
          end
        end
      end
      private :wait_on_pending_state

      # @api private
      #
      # create a usable wait time to wait between querying the service.
      #
      # @param [Integer] wait_hint the wait hint of a service in milliseconds
      # @return [Integer] the time to wait in seconds between querying the service
      def wait_hint_to_wait_time(wait_hint)

View on GitHub (pinned to e227c27540)

Solutions

  1. Increase the timeout: argument to Service.stop/start/resume, and let a large dwWaitHint extend it as designed.
  2. Diagnose the hang in the service (thread dump / hang dump with procdump) — the handler is stuck, this is a service bug, not a Puppet bug.
  3. As a workaround, schedule taskkill /F on the hung process after the timeout, then let Puppet re-establish state.
  4. Fix the service's control handler to advance dwCheckPoint and honor stop requests.
  5. Check event logs for the service's shutdown errors to find what it was blocked on.

Example fix

# before
Puppet::Util::Windows::Service.stop(service_name) # default timeout: 30

# after
Puppet::Util::Windows::Service.stop(service_name, timeout: 300) # honor long dwWaitHint stops
Defensive patterns

Strategy: retry

Try / catch

attempts = 0
begin
  attempts += 1
  Puppet::Util::Windows::Service.stop(name, timeout: 300)
rescue Puppet::Error => e
  raise unless e.message.include?('Timed out while waiting for the pending transition') && attempts < 2
  state = `sc query #{name}`
  if state =~ /STOP_PENDING/
    Puppet.warning("#{name} hung in STOP_PENDING; forcing")
    `taskkill /F /IM #{exe_name}`
    retry
  end
  raise
end

Prevention

When it happens

Trigger: Service hangs in STOP_PENDING because its handler blocks (waiting on a socket, thread deadlock) and stops advancing dwCheckPoint; a service that sets a huge dwWaitHint and hangs anyway; stop paths that ignore the control code; slow flush of large buffers to disk during shutdown.

Common situations: Database or agent services that hang on stop when their backend is unreachable; services with buggy control handlers that never update checkpoints; machines under heavy I/O during shutdown; Puppet ensure => stopped timing out and leaving the service in STOP_PENDING.

Understand the failure class

Related errors


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