hashicorp/terraform · critical

failed to generate initial lineage

Error message

failed to generate initial lineage: %v

What it means

Thrown by the cloud state writer when uuid.GenerateUUID() fails while seeding a new state's lineage. With no existing state snapshot (s.lineage == ''), the backend generates a fresh UUID as the lineage identifier; GenerateUUID reads from crypto/rand and only fails if the system's CSPRNG is unavailable. This is an extremely rare, environment-level failure.

Solutions

  1. Verify /dev/urandom is readable inside the execution environment (`head -c 16 /dev/urandom` succeeds).
  2. Relax the container/seccomp/AppArmor profile to allow the random device.
  3. Use a host with a healthy entropy source (e.g. virtio-rng on VMs).
  4. Retry after fixing the OS/entropy issue — once randomness is available, generation succeeds deterministically.
Defensive patterns

Strategy: validation

Validate before calling

// Verify the CSPRNG is available before state operations.
func randAvailable() error {
    f, err := os.Open("/dev/urandom")
    if err != nil { return err }
    return f.Close()
}

Try / catch

lineage, err := uuid.GenerateUUID()
if err != nil {
    return fmt.Errorf("failed to generate initial lineage: %v", err)
}

Prevention

When it happens

Trigger: uuid.GenerateUUID fails when crypto/rand cannot read randomness — typically a broken /dev/urandom, an OS-level entropy source failure, or a sandboxed/containerized environment that blocks the random device. This is essentially a host/OS defect, not a Terraform logic bug.

Common situations: A locked-down container or seccomp profile denying /dev/urandom access; an OS in early boot before the CSPRNG is seeded; a virtualized environment with a misconfigured entropy device; extremely rare hardware/kernel fault.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/4eb641f1bcca5171. Report an issue: GitHub.

Appendix: source

Thrown at internal/cloud/state.go:194

			// If the state, lineage or serial haven't changed at all then we have nothing to do.
			return nil
		}
		s.serial++
	} else {
		// We might be writing a new state altogether, but before we do that
		// we'll check to make sure there isn't already a snapshot present
		// that we ought to be updating.
		err := s.refreshState()
		if err != nil {
			return fmt.Errorf("failed checking for existing remote state: %s", err)
		}
		log.Printf("[DEBUG] cloud/state: after refresh, state read serial is: %d; serial is: %d", s.readSerial, s.serial)
		log.Printf("[DEBUG] cloud/state: after refresh, state read lineage is: %s; lineage is: %s", s.readLineage, s.lineage)

		if s.lineage == "" { // indicates that no state snapshot is present yet
			lineage, err := uuid.GenerateUUID()
			if err != nil {
				return fmt.Errorf("failed to generate initial lineage: %v", err)
			}
			s.lineage = lineage
			s.serial++
		}
	}

	f := statefile.New(s.state, s.lineage, s.serial)

	var buf bytes.Buffer
	err := statefile.Write(f, &buf)
	if err != nil {
		return err
	}

	var jsonState []byte
	if schemas != nil {
		jsonState, err = jsonstate.Marshal(f, schemas)
		if err != nil {

View on GitHub (pinned to d32a084675)