hashicorp/terraform · critical

missing field in set: %s.%s

Error message

missing field in set: %s.%s

What it means

A panic in `DiffFieldReader.readSet` (internal/legacy/helper/schema/field_reader_diff.go:214). While reconstructing a set from a diff, the reader iterates diff keys, reads each element via ReadField, and asserts the result `Exists`. If a key it just enumerated does not exist when re-read, it panics 'missing field in set: <key>.<idx>'. The comment notes 'This shouldn't happen because we just verified it does exist' — it is an internal consistency failure of the diff reader's own indexing.

Source

Thrown at internal/legacy/helper/schema/field_reader_diff.go:214

		if !strings.HasPrefix(k, prefix) {
			continue
		}
		if strings.HasSuffix(k, "#") {
			// Ignore any count field
			continue
		}

		// Split the key, since it might be a sub-object like "idx.field"
		parts := strings.Split(k[len(prefix):], ".")
		idx := parts[0]

		raw, err := r.ReadField(append(address, idx))
		if err != nil {
			return FieldReadResult{}, err
		}
		if !raw.Exists {
			// This shouldn't happen because we just verified it does exist
			panic("missing field in set: " + k + "." + idx)
		}

		set.Add(raw.Value)
	}

	// Determine if the set "exists". It exists if there are items or if
	// the diff explicitly wanted it empty.
	exists := set.Len() > 0
	if !exists {
		// We could check if the diff value is "0" here but I think the
		// existence of "#" on its own is enough to show it existed. This
		// protects us in the future from the zero value changing from
		// "0" to "" breaking us (if that were to happen).
		if _, ok := r.Diff.Attributes[prefix+"#"]; ok {
			exists = true
		}
	}

View on GitHub (pinned to c9def3e214)

Solutions

  1. Restore state from the most recent `.terraform.tfstate.backup` if state corruption is suspected.
  2. Re-plan from a clean state to regenerate the diff consistently.
  3. Ensure the provider version used for apply matches the one used for plan (set hashing must be stable across both).
  4. Report a provider/Terraform bug if reproduced with matching versions and a fresh plan.

Example fix

null
Defensive patterns

Strategy: validation

Validate before calling

// Go (provider): keep set element hashing stable across plan/apply
// Ensure Schema.Hash or nested Elem schema is identical between the version
// that planned and the version that applies; add a state migration on change.

Try / catch

// Go: recover from the readSet consistency panic
defer func() {
    if r := recover(); r != nil {
        res = FieldReadResult{}
        err = fmt.Errorf("set field consistency failure: %v; re-apply with a fresh plan", r)
    }
}()
res, err = r.readSet(address, schema)

Prevention

When it happens

Trigger: Applying/reading a diff that contains a set whose element keys were discovered via prefix scan but then resolve to non-existent fields on the nested ReadField call. Typically a symptom of a malformed diff, corrupted state, or a set element whose schema/hash changed between the plan and apply.

Common situations: Set element hashing changed (e.g. a provider altered the hash function / schema of a nested set block) so keys from the diff no longer map to existing fields; corrupted state with dangling set keys; race between concurrent state writes.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/701a743a71f11070. Report an issue: GitHub.