TL;DR: A `validation` block on a variable rejected your value. The error quotes the rule's `error_message` and shows the offending value. Change the value to satisfy the rule, or fix the rule if it's wrong. Nothing gets planned until every validation passes.

```text
Error: Invalid value for variable

  on main.tf line 16:
  16: variable "service" {
    ├────────────────
    │ var.environment is "prod"
    │ var.service.replicas is 1

A prod service needs at least 2 replicas (got 1).

This was checked by the validation rule at main.tf:27,3-13.
```

## Steps

1. Read the `error_message` line (`A prod service needs at least 2 replicas (got 1).`). That's the rule telling you what it wants.
   Expected: you know the constraint.
2. Look at the `│ var.X is ...` lines. That's the value you actually passed.
   Expected: you can see where the value came from (a `-var` flag, a tfvars file, a default).
3. Fix the value side: pass a compliant value (`-var='service={...replicas=2}'`) or update the tfvars file.
   Expected: `tofu plan` proceeds past validation.
4. If the value is correct and the rule is wrong, edit the `validation` block's `condition` instead.
   Expected: the rule accepts the legitimate value.

## When this applies

- `tofu plan` or `tofu apply` fails BEFORE any planning, with `Error: Invalid value for variable` and a quoted rule message.
- You just changed a variable value, a tfvars file, or the validation rule itself.

## When it doesn't apply

- `Error: Invalid value for input variable ... a string is required` is a TYPE error, not a validation rule; fix the type.
- `Error: Reference to undeclared input variable` means the variable doesn't exist at all.
- `Error: Invalid reference in variable validation` (pre-1.9) means the rule references another variable, which old versions forbid; upgrade to OpenTofu 1.9+ instead.

## Tool versions

All OpenTofu versions. OpenTofu 1.9 added cross-variable references inside validation blocks (a rule on one variable can read another).

## Why it happens

`validation` blocks are preconditions: tofu checks every variable value against its rules before doing anything else. A failing rule stops the run early on purpose, so a bad value can't half-plan your infrastructure.

## Edge cases

- The diagnostic points at the variable DECLARATION (`on main.tf line 16: variable "service"`), not at where you set the value. Trace the value back through `-var` flags, `*.tfvars` files, and `TF_VAR_` env vars.
- One bad value can produce several errors if the variable is passed into multiple modules; fix it once at the source.
- `nullable = false` plus a null default fails with a different message; that's the nullability check, not your rule.