{"record":{"id":"1ed96091d997773e","repo":"puppetlabs/puppet","slug":"timed-out-while-waiting-for-the-pending-transition","errorCode":null,"errorMessage":"Timed out while waiting for the pending transition from %{pending_state} to %{final_state} to finish. The current state is %{current_state}.","messagePattern":"Timed out while waiting for the pending transition from %(.+?) to %(.+?) to finish\\. The current state is %(.+?)\\.","errorType":"exception","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/windows/service.rb","lineNumber":667,"sourceCode":"            # the final_state OR if an unexpected transition\n            # has occurred\n            return if state == final_state\n            unless state == pending_state\n              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] }\n            end\n\n            # Check if any progress has been made since our last sleep\n            # using the dwCheckPoint. If no progress has been made then\n            # check if we've timed out, and raise an error if so\n            if checkpoint > last_checkpoint\n              elapsed_time = 0\n              last_checkpoint = checkpoint\n            else\n              wait_hint = milliseconds_to_seconds(status[:dwWaitHint])\n              timeout = wait_hint < timeout ? timeout : wait_hint\n\n              if elapsed_time >= timeout\n                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] }\n              end\n            end\n            wait_time = wait_hint_to_wait_time(wait_hint)\n            # Wait a bit before rechecking the service's state\n            sleep(wait_time)\n            elapsed_time += wait_time\n          end\n        end\n      end\n      private :wait_on_pending_state\n\n      # @api private\n      #\n      # create a usable wait time to wait between querying the service.\n      #\n      # @param [Integer] wait_hint the wait hint of a service in milliseconds\n      # @return [Integer] the time to wait in seconds between querying the service\n      def wait_hint_to_wait_time(wait_hint)","sourceCodeStart":649,"sourceCodeEnd":685,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/windows/service.rb#L649-L685","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Increase the timeout: argument to Service.stop/start/resume, and let a large dwWaitHint extend it as designed.","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.","As a workaround, schedule taskkill /F on the hung process after the timeout, then let Puppet re-establish state.","Fix the service's control handler to advance dwCheckPoint and honor stop requests.","Check event logs for the service's shutdown errors to find what it was blocked on."],"exampleFix":"# before\nPuppet::Util::Windows::Service.stop(service_name) # default timeout: 30\n\n# after\nPuppet::Util::Windows::Service.stop(service_name, timeout: 300) # honor long dwWaitHint stops","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"attempts = 0\nbegin\n  attempts += 1\n  Puppet::Util::Windows::Service.stop(name, timeout: 300)\nrescue Puppet::Error => e\n  raise unless e.message.include?('Timed out while waiting for the pending transition') && attempts < 2\n  state = `sc query #{name}`\n  if state =~ /STOP_PENDING/\n    Puppet.warning(\"#{name} hung in STOP_PENDING; forcing\")\n    `taskkill /F /IM #{exe_name}`\n    retry\n  end\n  raise\nend","preventionTips":["Size the timeout: argument to exceed the service's longest advertised dwWaitHint shutdown.","Fix service control handlers to advance dwCheckPoint so waiters can distinguish progress from hangs.","Watch for STOP_PENDING zombies with monitoring and alert before automation hits them."],"tags":["windows","win32","service","timeout","stop-pending","checkpoint","puppet"],"backgroundTag":"service-operation-timeout","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}