Lightning-AI/pytorch-lightning · error · ValueError
`val_check_interval` ({trainer.val_check_interval}) must be
Error message
`val_check_interval` ({trainer.val_check_interval}) must be less than or equal to the number of the training batches ({self.max_batches}). If you want to disable validation set `limit_val_batches` to 0.0 instead. If you want to validate based on the total training batches, set `check_val_every_n_epoch=None`. What it means
Raised in FitLoop.setup_data when an integer `val_check_interval` exceeds the total number of training batches in the epoch while validation is actually enabled (check_val_every_n_epoch is not None and limit_val_batches > 0). Lightning cannot schedule a validation check after more batches than exist, so it refuses rather than silently never validating.
Source
Thrown at src/lightning/pytorch/loops/fit_loop.py:300
return
# store epoch of dataloader reset for reload_dataloaders_every_n_epochs
self._last_train_dl_reload_epoch = trainer.current_epoch
# If time-based validation is enabled, disable batch-based scheduling here.
# Use None to clearly signal "no batch-based validation"; wall-time logic will run elsewhere.
if getattr(trainer, "_val_check_time_interval", None) is not None:
trainer.val_check_batch = None
trainer._train_start_time = time.monotonic()
trainer._last_val_time = trainer._train_start_time
elif isinstance(trainer.val_check_interval, int):
trainer.val_check_batch = trainer.val_check_interval
if (
trainer.val_check_batch > self.max_batches
and trainer.check_val_every_n_epoch is not None
and trainer.limit_val_batches > 0
):
raise ValueError(
f" `val_check_interval` ({trainer.val_check_interval}) must be less than or equal"
f" to the number of the training batches ({self.max_batches})."
" If you want to disable validation set `limit_val_batches` to 0.0 instead."
" If you want to validate based on the total training batches, set `check_val_every_n_epoch=None`."
)
else:
if not has_len_all_ranks_:
if trainer.val_check_interval == 1.0:
trainer.val_check_batch = float("inf")
else:
raise MisconfigurationException(
"When using an IterableDataset for `train_dataloader`,"
" `Trainer(val_check_interval)` must be time based, `1.0` or an int. An int k specifies"
" checking validation every k training batches."
)
else:
trainer.val_check_batch = int(self.max_batches * trainer.val_check_interval)
trainer.val_check_batch = max(1, trainer.val_check_batch)View on GitHub (pinned to 9fed5c27d2)
Solutions
- Reduce val_check_interval to be <= number of training batches (commonly 1.0 or a small int)
- If validation should not run, set `limit_val_batches=0.0`
- If you want the interval interpreted against total training batches across epochs, set `check_val_every_n_epoch=None`
- Increase available training batches by raising limit_train_batches or lowering batch size
Example fix
# before trainer = pl.Trainer(val_check_interval=5000) # epoch only has 100 batches # after trainer = pl.Trainer(val_check_interval=100) # or 1.0 to validate once per epoch
Defensive patterns
Strategy: validation
Validate before calling
n_batches = len(train_dataloader) // trainer_config.get('limit_train_batches_len', 1.0)
vci = trainer_config['val_check_interval']
if isinstance(vci, int) and vci > n_batches:
vci = max(1, n_batches) # or 1.0
trainer = pl.Trainer(val_check_interval=vci) Type guard
def interval_ok(vci: int, n_batches: int) -> bool:
return vci <= n_batches Prevention
- Derive val_check_interval from the dataloader length instead of hardcoding
- When running smoke tests with limit_train_batches, scale val_check_interval down too
- Prefer fractional 1.0 or small ints unless batch-count precision is needed
When it happens
Trigger: Setting `Trainer(val_check_interval=1000)` when the training dataloader yields fewer than 1000 batches per epoch; or a fractional val_check_interval times max_batches rounds down to 0 forcing a batch-based interval larger than the epoch; small datasets combined with large int val_check_interval values.
Common situations: Copying a Trainer config from a large-dataset experiment to a small smoke-test dataset; limiting train batches via limit_train_batches so the effective batch count drops below val_check_interval; changing batch size upward so fewer steps per epoch remain.
Related errors
- Device should be CUDA, got {device} instead.
- You requested to find {num_devices} devices but there are no
- You requested to find {num_devices} devices but only {len(av
- Device should be MPS, got {device} instead.
- `setup_optimizers` requires at least one optimizer as input.
AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28).
Data as JSON: /api/errors/4d605ffc6fe32239.
Report an issue: GitHub.