Lightning-AI/pytorch-lightning · error · MisconfigurationException
`max_epochs` must be a non-negative integer or -1. You passe
Error message
`max_epochs` must be a non-negative integer or -1. You passed in {max_epochs}. What it means
Raised by the FitLoop constructor when the `max_epochs` argument passed to `Trainer(max_epochs=...)` is an integer strictly less than -1. Lightning treats -1 as 'infinite epochs' and 0 as a valid value handled later by fit_loop.done, so any value below -1 is rejected as a misconfiguration.
Source
Thrown at src/lightning/pytorch/loops/fit_loop.py:96
...
...
Args:
min_epochs: The minimum number of epochs
max_epochs: The maximum number of epochs, can be set -1 to turn this limit off
"""
def __init__(
self,
trainer: "pl.Trainer",
min_epochs: Optional[int] = 0,
max_epochs: Optional[int] = None,
) -> None:
super().__init__(trainer)
if isinstance(max_epochs, int) and max_epochs < -1:
# Allow max_epochs to be zero, since this will be handled by fit_loop.done
raise MisconfigurationException(
f"`max_epochs` must be a non-negative integer or -1. You passed in {max_epochs}."
)
self.max_epochs = max_epochs
self.min_epochs = min_epochs
self.epoch_loop = _TrainingEpochLoop(trainer)
self.epoch_progress = _Progress()
self.max_batches: Union[int, float] = float("inf")
self._data_source = _DataLoaderSource(None, "train_dataloader")
self._combined_loader: Optional[CombinedLoader] = None
self._combined_loader_states_to_load: list[dict[str, Any]] = []
self._data_fetcher: Optional[_DataFetcher] = None
self._last_train_dl_reload_epoch = float("-inf")
self._restart_stage = RestartStage.NONE
@property
def total_batch_idx(self) -> int:View on GitHub (pinned to 9fed5c27d2)
Solutions
- Set max_epochs to a non-negative integer (e.g. 10) or -1 for infinite training
- Check intermediate config values: print/log max_epochs right before Trainer construction to find where it becomes < -1
- If parsing from CLI/config, coerce and clamp the value (e.g. `max(max_epochs, -1)` if infinite is intended)
Example fix
# before trainer = pl.Trainer(max_epochs=n_epochs - 3) # n_epochs=2 -> -1 ok, but n_epochs=1 -> -2 raises # after trainer = pl.Trainer(max_epochs=max(n_epochs - 3, 1))
Defensive patterns
Strategy: validation
Validate before calling
def safe_max_epochs(v):
if isinstance(v, int) and v < -1:
raise ValueError(f"max_epochs must be >= -1, got {v}")
return v
trainer = pl.Trainer(max_epochs=safe_max_epochs(cfg['max_epochs'])) Type guard
def is_valid_max_epochs(v) -> bool:
return not isinstance(v, int) or v >= -1 Prevention
- Validate integer hyperparameters in config loading (pydantic/jsonschema) before constructing the Trainer
- Clamp sentinel arithmetic: max(max_epochs, -1) when -1 means infinite
- Log the final Trainer kwargs at startup for auditability
When it happens
Trigger: Instantiating `pl.Trainer(max_epochs=-2)` or any more negative int (e.g. -5). Also occurs when max_epochs is computed from config arithmetic that underflows (e.g. `max_epochs=some_value - 3` yielding a negative result).
Common situations: Typos or off-by-one math in training scripts; YAML/JSON config files with a negated or misparsed integer; CLI flags parsed as negative numbers; conditional configs like `max_epochs=-1 if resume else epochs` where a bug produces -2 or lower.
Related errors
- No `{step_name}()` method defined to run `Trainer.{trainer_m
- Device should be CUDA, got {device} instead.
- You requested to find {num_devices} devices but there are no
- `max_steps` must be a non-negative integer or -1 (infinite s
- You requested to find {num_devices} devices but this machine
AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28).
Data as JSON: /api/errors/d01980641774aa5a.
Report an issue: GitHub.