{"record":{"id":"b2fe986efb1a491c","repo":"apache/hadoop","slug":"name-cannot-enter-state-proposed-from-state","errorCode":null,"errorMessage":"${name} cannot enter state ${proposed} from state ${state}","messagePattern":"(.+?) cannot enter state (.+?) from state (.+?)","errorType":"exception","errorClass":"ServiceStateException","httpStatus":null,"severity":"error","filePath":"hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/service/ServiceStateModel.java","lineNumber":132,"sourceCode":"    checkStateTransition(name, state, proposed);\n    Service.STATE oldState = state;\n    //atomic write of the new state\n    state = proposed;\n    return oldState;\n  }\n\n  /**\n   * Check that a state tansition is valid and\n   * throw an exception if not\n   * @param name name of the service (can be null)\n   * @param state current state\n   * @param proposed proposed new state\n   */\n  public static void checkStateTransition(String name,\n                                          Service.STATE state,\n                                          Service.STATE proposed) {\n    if (!isValidStateTransition(state, proposed)) {\n      throw new ServiceStateException(name + \" cannot enter state \"\n                                      + proposed + \" from state \" + state);\n    }\n  }\n\n  /**\n   * Is a state transition valid?\n   * There are no checks for current==proposed\n   * as that is considered a non-transition.\n   *\n   * using an array kills off all branch misprediction costs, at the expense\n   * of cache line misses.\n   *\n   * @param current current state\n   * @param proposed proposed new state\n   * @return true if the transition to a new state is valid\n   */\n  public static boolean isValidStateTransition(Service.STATE current,\n                                               Service.STATE proposed) {","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/service/ServiceStateModel.java#L114-L150","documentation":"ServiceStateModel.checkStateTransition enforces the legal lifecycle matrix (NOTINITED->INITED/STOPPED, INITED->STARTED/STOPPED, STARTED->STOPPED; STOPPED is terminal). Proposing an illegal transition throws ServiceStateException \"<name> cannot enter state <proposed> from state <state>\". This is how misordered lifecycle calls (init after start, re-init after stop) are caught instead of silently corrupting service state.","triggerScenarios":"Calling service.init(conf) after start(); start() before init(); re-initializing a STOPPED service instead of creating a new instance; direct ServiceStateModel.enterState/checkStateTransition misuse in custom services; double init from overlapping threads bypassing AbstractService's synchronized guard.","commonSituations":"Test setups that init twice; restart logic that tries to reuse a stopped service instance; CompositeService calling child.init() inside serviceStart; refactors that move init calls.","solutions":["Follow the one-way lifecycle: init(conf) -> start() -> stop(), each at most once per instance.","To 'restart', build a new service instance rather than re-initing a stopped one.","Guard transitions with isInState() checks (e.g. only init when NOTINITED) before calling lifecycle methods.","In custom code use AbstractService.enterState via super calls so the model validates transitions for you."],"exampleFix":"// before: reuse + re-init of a stopped service\nstoppedService.init(newConf); // \"cannot enter state INITED from state STOPPED\"\n// after: fresh instance per lifecycle\nService s = serviceClass.newInstance();\ns.init(newConf);\ns.start();","handlingStrategy":"validation","validationCode":"// Legal preconditions per transition\nif (svc.isInState(Service.STATE.NOTINITED)) svc.init(conf);\nif (svc.isInState(Service.STATE.INITED)) svc.start();\nif (svc.isInState(Service.STATE.STARTED)) svc.stop();","typeGuard":"boolean canInit(Service s)   { return s.isInState(Service.STATE.NOTINITED); }\nboolean canStart(Service s) { return s.isInState(Service.STATE.INITED); }\nboolean canStop(Service s)  { return s.isInState(Service.STATE.STARTED)\n    || s.isInState(Service.STATE.INITED)\n    || s.isInState(Service.STATE.NOTINITED); }","tryCatchPattern":"try {\n  svc.init(conf);\n} catch (ServiceStateException e) {\n  // message: \"cannot enter state INITED from state STARTED\"\n  // -> fix lifecycle ordering or build a fresh service instance\n}","preventionTips":["Run each lifecycle transition at most once per instance: init -> start -> stop.","Create a new service instance to restart; never re-init a STOPPED one.","In composites, init children in serviceInit, not serviceStart."],"tags":["service","lifecycle","state-machine","illegal-transition"],"backgroundTag":"invalid-state-transition","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}