{"record":{"id":"c2f8dce74a572a91","repo":"Lightning-AI/pytorch-lightning","slug":"you-restored-a-checkpoint-with-current-epoch-self","errorCode":null,"errorMessage":"You restored a checkpoint with current_epoch={self.trainer.current_epoch}, but you have set Trainer(max_epochs={self.trainer.max_epochs}).","messagePattern":"You restored a checkpoint with current_epoch=(.+?), but you have set Trainer\\(max_epochs=(.+?)\\)\\.","errorType":"validation","errorClass":"MisconfigurationException","httpStatus":null,"severity":"error","filePath":"src/lightning/pytorch/trainer/connectors/checkpoint_connector.py","lineNumber":362,"sourceCode":"            if self.trainer.state.fn == TrainerFn.FITTING:\n                fit_loop.load_state_dict(state_dict[\"fit_loop\"])\n            elif self.trainer.state.fn == TrainerFn.VALIDATING:\n                self.trainer.validate_loop.load_state_dict(state_dict[\"validate_loop\"])\n            elif self.trainer.state.fn == TrainerFn.TESTING:\n                self.trainer.test_loop.load_state_dict(state_dict[\"test_loop\"])\n            elif self.trainer.state.fn == TrainerFn.PREDICTING:\n                self.trainer.predict_loop.load_state_dict(state_dict[\"predict_loop\"])\n\n        if self.trainer.state.fn != TrainerFn.FITTING:\n            return\n\n        # crash if max_epochs is lower then the current epoch from the checkpoint\n        if (\n            self.trainer.max_epochs != -1\n            and self.trainer.max_epochs is not None\n            and self.trainer.current_epoch > self.trainer.max_epochs\n        ):\n            raise MisconfigurationException(\n                f\"You restored a checkpoint with current_epoch={self.trainer.current_epoch},\"\n                f\" but you have set Trainer(max_epochs={self.trainer.max_epochs}).\"\n            )\n\n    def restore_optimizers_and_schedulers(self) -> None:\n        \"\"\"Restores the optimizers and learning rate scheduler states from the pre-loaded checkpoint.\"\"\"\n        if not self._loaded_checkpoint:\n            return\n\n        if self.trainer.strategy.lightning_restore_optimizer:\n            # validation\n            if \"optimizer_states\" not in self._loaded_checkpoint:\n                raise KeyError(\n                    \"Trying to restore optimizer state but checkpoint contains only the model.\"\n                    \" This is probably due to `ModelCheckpoint.save_weights_only` being set to `True`.\"\n                )\n            self.restore_optimizers()\n","sourceCodeStart":344,"sourceCodeEnd":380,"githubUrl":"https://github.com/Lightning-AI/pytorch-lightning/blob/9fed5c27d2a62ff0efd6c3573599921d6ff67c14/src/lightning/pytorch/trainer/connectors/checkpoint_connector.py#L344-L380","documentation":"Raised in restore_loops after a checkpoint is loaded: the restored current_epoch exceeds the configured max_epochs, which would mean training ends immediately (or loops incorrectly). Lightning refuses instead of silently doing zero epochs. max_epochs=-1 (no limit) or None are exempt.","triggerScenarios":"Resuming a checkpoint from epoch 10 with Trainer(max_epochs=10) or any max_epochs < restored current_epoch; common when retraining with a smaller budget or when max_epochs is mistakenly treated as additional epochs.","commonSituations":"Users expect fit(ckpt_path=...) to add N more epochs; fine-tuning pipelines that reduce the epoch budget; resuming a finished run to continue training without raising the cap.","solutions":["Raise the limit: Trainer(max_epochs=<value greater than the restored current_epoch>)","Use max_epochs=-1 to disable the epoch cap entirely","Start a fresh Trainer without resuming the epoch loop if you only want the weights (load weights via load_from_checkpoint instead of ckpt_path resume)"],"exampleFix":"# before\ntrainer = Trainer(max_epochs=10)\ntrainer.fit(model, ckpt_path=\"epoch=9.ckpt\")  # restored epoch 9... e.g. restored current_epoch=10 > 10 variants\n# after\ntrainer = Trainer(max_epochs=20)  # or -1\ntrainer.fit(model, ckpt_path=\"epoch=9.ckpt\")","handlingStrategy":"validation","validationCode":"import torch\nckpt = torch.load(path, map_location=\"cpu\", weights_only=False)\nrestored = ckpt.get(\"epoch\", -1)\nif max_epochs not in (-1, None):\n    assert restored < max_epochs, f\"restored epoch {restored} >= max_epochs {max_epochs}\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Read the checkpoint's epoch before resuming","Use max_epochs=-1 for open-ended continuation","Load weights only (load_from_checkpoint) when you want a fresh epoch loop"],"tags":["lightning","resume","max-epochs","epoch","trainer-state"],"backgroundTag":"resume-epoch-limit-exceeded","analyzedSha":"9fed5c27d2a62ff0efd6c3573599921d6ff67c14","analyzedAt":"2026-08-28T11:52:41.083Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}