Lightning-AI/pytorch-lightning · error · RuntimeError
Early stopping conditioned on metric `{self.monitor}` which
Error message
Early stopping conditioned on metric `{self.monitor}` which is not available. Pass in or modify your `EarlyStopping` callback to use any of the following: `{'`, `'.join(list(logs.keys()))}` What it means
EarlyStopping checks that the metric named by `monitor` exists in the current logged metrics (`logs`). When it is missing and `strict=True` (the default), a RuntimeError is raised telling you which keys ARE available. With `strict=False` it only warns and skips the check for that epoch.
Source
Thrown at src/lightning/pytorch/callbacks/early_stopping.py:175
@override
def setup(self, trainer: "pl.Trainer", pl_module: "pl.LightningModule", stage: str) -> None:
if self._check_on_train_epoch_end is None:
# if the user runs validation multiple times per training epoch or multiple training epochs without
# validation, then we run after validation instead of on train epoch end
self._check_on_train_epoch_end = trainer.val_check_interval == 1.0 and trainer.check_val_every_n_epoch == 1
def _validate_condition_metric(self, logs: dict[str, Tensor]) -> bool:
monitor_val = logs.get(self.monitor)
error_msg = (
f"Early stopping conditioned on metric `{self.monitor}` which is not available."
" Pass in or modify your `EarlyStopping` callback to use any of the following:"
f" `{'`, `'.join(list(logs.keys()))}`"
)
if monitor_val is None:
if self.strict:
raise RuntimeError(error_msg)
if self.verbose > 0:
rank_zero_warn(error_msg, category=RuntimeWarning)
return False
return True
@property
def monitor_op(self) -> Callable:
return self.mode_dict[self.mode]
@override
def state_dict(self) -> dict[str, Any]:
return {
"wait_count": self.wait_count,
"stopped_epoch": self.stopped_epoch,
"best_score": self.best_score,
"patience": self.patience,View on GitHub (pinned to 9fed5c27d2)
Solutions
- Read the error message: it lists the available keys — pick the correct one and set it as `monitor`
- Ensure `self.log(self.monitor_name, value)` is called in the module (e.g. in validation_step or training_step)
- If the metric legitimately appears late, pass `check_finite=False`, `check_on_train_epoch_end` appropriately, or `strict=False` to downgrade to a warning
Example fix
# before
EarlyStopping(monitor='val_loss') # module logs 'loss'
# after
self.log('val_loss', loss, prog_bar=True) # in validation_step
EarlyStopping(monitor='val_loss') Defensive patterns
Strategy: validation
Validate before calling
# before fit: assert the module will log the monitor key monitor = 'val_loss' assert hasattr(lightning_module, 'validation_step'), 'metric must come from validation'
Try / catch
try:
trainer.fit(model)
except RuntimeError as e:
if 'could not find' in str(e) or 'not available' in str(e):
# parse available keys from the message and fix monitor
raise Prevention
- Log every monitored metric with prog_bar=True so it appears in console/logs
- Keep a single constant for the metric name used in both self.log and monitor
- Run a 1-epoch smoke fit in CI to catch name mismatches early
When it happens
Trigger: `EarlyStopping(monitor='val_loss')` but the LightningModule never calls `self.log('val_loss', ...)`; or the key is logged under a different name ('loss', 'val/loss'). The `_validate_condition_metric` runs inside `_run_early_stopping_check` during training/validation.
Common situations: Renaming the logged metric but forgetting to update the monitor string; using a step-level log key when EarlyStopping checks epoch-level aggregates; monitor metric logged only on a subset of processes or only after N epochs.
Related errors
- `ModelCheckpoint(monitor={self.monitor!r})` could not find t
- `mode` can be {', '.join(self.mode_dict.keys())}, got {self.
- `configure_optimizers` must include a monitor when a `Reduce
- `.{fn}(ckpt_path="best")` is set but `ModelCheckpoint` is no
- Received multiple values for {', '.join(duplicated_plugin_ke
AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28).
Data as JSON: /api/errors/52aa66001e319920.
Report an issue: GitHub.