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

  1. Reduce val_check_interval to be <= number of training batches (commonly 1.0 or a small int)
  2. If validation should not run, set `limit_val_batches=0.0`
  3. If you want the interval interpreted against total training batches across epochs, set `check_val_every_n_epoch=None`
  4. 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

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


AI-assisted analysis of Lightning-AI/pytorch-lightning@9fed5c27d2 (2026-08-28). Data as JSON: /api/errors/4d605ffc6fe32239. Report an issue: GitHub.