{"record":{"id":"3a3542e6b1618455","repo":"puppetlabs/puppet","slug":"the-service-must-be-in-one-of-the-valid-initial","errorCode":null,"errorMessage":"The service must be in one of the %{valid_initial_states} states to perform this transition. It is currently in the %{current_state} state.","messagePattern":"The service must be in one of the %(.+?) states to perform this transition\\. It is currently in the %(.+?) state\\.","errorType":"exception","errorClass":"Puppet::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/windows/service.rb","lineNumber":362,"sourceCode":"        open_service(service_name, SC_MANAGER_CONNECT, service_access) do |service|\n          query_status(service) do |status|\n            initial_state = status[:dwCurrentState]\n            # If the service is already in the final_state, then\n            # no further work needs to be done\n            if initial_state == final_state\n              Puppet.debug _(\"The service is already in the %{final_state} state. No further work needs to be done.\") % { final_state: SERVICE_STATES[final_state] }\n\n              next\n            end\n\n            # Check that initial_state corresponds to a valid\n            # initial state\n            unless valid_initial_states.include?(initial_state)\n              valid_initial_states_str = valid_initial_states.map do |state|\n                SERVICE_STATES[state]\n              end.join(\", \")\n\n              raise Puppet::Error, _(\"The service must be in one of the %{valid_initial_states} states to perform this transition. It is currently in the %{current_state} state.\") % { valid_initial_states: valid_initial_states_str, current_state: SERVICE_STATES[initial_state] }\n            end\n\n            # Check if there's a pending transition to the final_state. If so, then wait for\n            # that transition to finish.\n            possible_pending_states = FINAL_STATES.keys.select do |pending_state|\n              # SERVICE_RUNNING has two pending states, SERVICE_START_PENDING and\n              # SERVICE_CONTINUE_PENDING. That is why we need the #select here\n              FINAL_STATES[pending_state] == final_state\n            end\n            if possible_pending_states.include?(initial_state)\n              Puppet.debug _(\"There is already a pending transition to the %{final_state} state for the %{service_name} service.\") % { final_state: SERVICE_STATES[final_state], service_name: service_name }\n              wait_on_pending_state(service, initial_state, timeout)\n\n              next\n            end\n\n            # If we are in an unsafe pending state like SERVICE_START_PENDING\n            # or SERVICE_STOP_PENDING, then we want to wait for that pending","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/windows/service.rb#L344-L380","documentation":"Raised inside transition_service_state when the service's current state is not among the valid initial states for the requested transition. start() only accepts STOPPED, STOP_PENDING, and START_PENDING; stop() accepts everything except STOPPED; resume() requires PAUSED/PAUSE_PENDING. So, for example, starting a paused service or resuming a running one trips this before any control call is made.","triggerScenarios":"Calling start while the service is SERVICE_PAUSED or SERVICE_PAUSE_PENDING; calling resume on a service that is SERVICE_RUNNING; calling stop on an already-stopped service raced between the exists/state check and the transition; any transition attempted from a state the API's valid_initial_states list excludes.","commonSituations":"Idempotency code that assumes 'running' without checking state first; races where another admin or monitor changes service state concurrently; manifests that both stop and start a service in the same run while it is mid-transition.","solutions":["Query Puppet::Util::Windows::Service.service_state(service_name) and branch before calling start/stop/resume","For start, first resume-or-stop a paused service (or set it to stopped) so it lands in an accepted initial state","Re-fetch state and retry once on this specific error, since state may have changed between check and call","Reduce concurrent external service control (monitoring restarts) while the code transitions services"],"exampleFix":"// before\nPuppet::Util::Windows::Service.start('myservice')\n\n# after\nstate = Puppet::Util::Windows::Service.service_state('myservice')\nif state == :SERVICE_PAUSED\n  # paused is not a valid initial state for start\n  Puppet::Util::Windows::Service.stop('myservice')\nend\nPuppet::Util::Windows::Service.start('myservice')","handlingStrategy":"validation","validationCode":"state = Puppet::Util::Windows::Service.service_state(name)\nVALID_FOR_START = [:SERVICE_STOPPED, :SERVICE_STOP_PENDING, :SERVICE_START_PENDING].freeze\nunless VALID_FOR_START.include?(state)\n  Puppet::Util::Windows::Service.stop(name) if state == :SERVICE_PAUSED\nend\nPuppet::Util::Windows::Service.start(name)","typeGuard":"def startable_state?(state)\n  [:SERVICE_STOPPED, :SERVICE_STOP_PENDING, :SERVICE_START_PENDING].include?(state)\nend","tryCatchPattern":"begin\n  Puppet::Util::Windows::Service.start(name)\nrescue Puppet::Error => e\n  retry if e.message.include?('must be in one of the') # state changed between check and call\n  raise\nend","preventionTips":["Query service_state and branch per-API allowed initial states before transitioning","Treat 'paused' as a state start() rejects; stop or resume it first","Expect one retry: state can change between your check and the transition"],"tags":["windows","service","win32","state-machine","scm"],"backgroundTag":"invalid-service-state-transition","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}