{"record":{"id":"6ccf7c73f14b24ec","repo":"puppetlabs/puppet","slug":"failed-to-send-the-control-signal-signal-to-the","errorCode":null,"errorMessage":"Failed to send the %{control_signal} signal to the service. Its current state is %{current_state}. Reason for failure:","messagePattern":"Failed to send the %(.+?) signal to the service\\. Its current state is %(.+?)\\. Reason for failure:","errorType":"exception","errorClass":"Puppet::Util::Windows::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/windows/service.rb","lineNumber":574,"sourceCode":"      # @param [String] service_name name of service\n      # @param [Bool] delayed whether the service should be started with a delay or not\n      def set_startup_mode_delayed(service_name, delayed)\n        delayed_start = SERVICE_DELAYED_AUTO_START_INFO.new\n        delayed_start[:fDelayedAutostart] = delayed\n        set_optional_parameter(service_name, SERVICE_CONFIG_DELAYED_AUTO_START_INFO, delayed_start)\n      end\n      private :set_startup_mode_delayed\n\n      # @api private\n      # Sends a service control signal to a service\n      #\n      # @param [:handle] service handle to the service\n      # @param [Integer] signal the service control signal to send\n      def send_service_control_signal(service, signal)\n        FFI::MemoryPointer.new(SERVICE_STATUS.size) do |status_ptr|\n          status = SERVICE_STATUS.new(status_ptr)\n          if ControlService(service, signal, status) == FFI::WIN32_FALSE\n            raise Puppet::Util::Windows::Error, _(\"Failed to send the %{control_signal} signal to the service. Its current state is %{current_state}. Reason for failure:\") % { control_signal: SERVICE_CONTROL_SIGNALS[signal], current_state: SERVICE_STATES[status[:dwCurrentState]] }\n          end\n        end\n      end\n\n      # @api private\n      # Waits for a service to transition from one state to\n      # another state.\n      #\n      # @param [:handle] service handle to the service to wait on\n      # @param [Integer] initial_state the state that the service is transitioning from.\n      # @param [Integer] final_state the state that the service is transitioning to\n      # @param [Integer] timeout the minumum number of seconds to wait before timing out\n      def wait_on_state_transition(service, initial_state, final_state, timeout)\n        # Get the pending state for this transition. Note that SERVICE_RUNNING\n        # has two possible pending states, which is why we need this logic.\n        if final_state != SERVICE_RUNNING\n          pending_state = FINAL_STATES.key(final_state)\n        elsif initial_state == SERVICE_STOPPED","sourceCodeStart":556,"sourceCodeEnd":592,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/windows/service.rb#L556-L592","documentation":"Raised by send_service_control_signal when the Win32 ControlService call fails to deliver a control code (stop, pause, continue) to a service. The message includes the signal name from SERVICE_CONTROL_SIGNALS and the service's current state from SERVICE_STATES at the moment of failure, plus the GetLastError reason appended by Puppet::Util::Windows::Error. It is a plain wrapper failure of the SCM control channel, not a timeout.","triggerScenarios":"Sending SERVICE_CONTROL_STOP to a service already in STOPPED state (ERROR_SERVICE_NOT_ACTIVE); sending a control the service does not accept in its accepted-controls mask (ERROR_INVALID_SERVICE_CONTROL); ControlService on a service in a transition-pending state; ERROR_ACCESS_DENIED when the handle lacks SERVICE_PAUSE_CONTINUE/SERVICE_STOP access.","commonSituations":"Puppet's ensure => stopped racing with a service that stops itself (or a previous Puppet run) so the STOP arrives when the state is already stopped; manifest declaring pause/continue for a service that never called SetServiceStatus with those accepted controls; running non-elevated against services with restrictive DACLs.","solutions":["Re-check the current state right before signalling (`sc query <name>`) and skip the signal if the service is already in the target state.","If the message says current state is 'stopped' and the signal is 'SERVICE_CONTROL_STOP', make the resource idempotent (Puppet normally pre-checks via query_status; verify a custom type does too).","Run elevated as Administrator so the service handle carries the needed control access rights.","For ERROR_INVALID_SERVICE_CONTROL, update the service to accept the control (its dispatcher sets dwControlsAccepted) or stop requesting pause/continue for it.","Retry once after a short delay if the service was in a pending state (the SCM can reject controls mid-transition)."],"exampleFix":"# before\nService.stop(service_name) # internally: ControlService(svc, SERVICE_CONTROL_STOP, status)\n\n# after - only signal when the service reports a state that accepts it\nPuppet::Util::Windows::Service.query_status(service_handle) do |status|\n  state = status[:dwCurrentState]\n  break if state == Puppet::Util::Windows::Service::SERVICE_STOPPED\n  Service.stop(service_name)\nend","handlingStrategy":"try-catch","validationCode":"# check the service's current state and accepted controls before signalling\nPuppet::Util::Windows::Service.query_status(svc_handle) do |st|\n  return if st[:dwCurrentState] == SERVICE_STOPPED # nothing to stop\nend","typeGuard":null,"tryCatchPattern":"begin\n  Service.stop(name)\nrescue Puppet::Util::Windows::Error => e\n  case e.code\n  when 1062 then nil # ERROR_SERVICE_NOT_ACTIVE: already stopped, treat as success\n  when 400 then raise \"service does not accept this control\" # ERROR_INVALID_SERVICE_CONTROL\n  else raise\n  end\nend","preventionTips":["Query the state immediately before sending a control signal; never assume the state from earlier checks.","Treat ERROR_SERVICE_NOT_ACTIVE on stop as idempotent success.","Only request pause/continue for services whose dwControlsAccepted includes them."],"tags":["windows","win32","service","scm","control-signal","puppet"],"backgroundTag":"windows-service-control-failed","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}