hashicorp/terraform · error

lost consul lock, cannot re-lock

Error message

lost consul lock, cannot re-lock

What it means

NestingGroup blocks cannot be marked Computed. NestingGroup guarantees the block is always present (never null) with attribute defaults, which conflicts with the Computed semantics where the provider supplies the value. Combining them is rejected.

Source

Thrown at internal/backend/remote-state/consul/client.go:378

}

func (c *RemoteClient) Lock(info *statemgr.LockInfo) (string, error) {
	c.mu.Lock()
	defer c.mu.Unlock()

	if !c.lockState {
		return "", nil
	}

	c.info = info

	// These checks only are to ensure we strictly follow the specification.
	// Terraform shouldn't ever re-lock, so provide errors for the 2 possible
	// states if this is called.
	select {
	case <-c.lockCh:
		// We had a lock, but lost it.
		return "", errors.New("lost consul lock, cannot re-lock")
	default:
		if c.lockCh != nil {
			// we have an active lock already
			return "", fmt.Errorf("state %q already locked", c.Path)
		}
	}

	return c.lock()
}

// the lock implementation.
// Only to be called while holding Client.mu
func (c *RemoteClient) lock() (string, error) {
	// We create a new session here, so it can be canceled when the lock is
	// lost or unlocked.
	lockSession, err := c.createSession()
	if err != nil {
		return "", err

View on GitHub (pinned to d32a084675)

Solutions

  1. Set Computed: false on the NestingGroup block (group attributes can still be individually Computed).
  2. If you need a computed single instance, use NestingSingle with Computed instead of NestingGroup.

Example fix

// before
"defaults": {
  Nesting: configschema.NestingGroup,
  Block: configschema.Block{Computed: true},
},
// after
"defaults": {
  Nesting: configschema.NestingGroup,
  Block: configschema.Block{
    Attributes: map[string]*configschema.Attribute{
      "value": { Type: cty.String, Computed: true, Optional: true },
    },
  },
},
Defensive patterns

Strategy: validation

Validate before calling

// NestingGroup must not be Computed.
func validGroupComputed(nb *configschema.NestedBlock) bool {
    return nb.Nesting != configschema.NestingGroup || !nb.Computed
}

Type guard

func groupNotComputed(nesting configschema.NestingMode, computed bool) bool {
    return nesting != configschema.NestingGroup || !computed
}

Prevention

When it happens

Trigger: A NestedBlock with Nesting: NestingGroup and Computed: true. Guard at internal_validate.go:85 is `blockS.Computed`.

Common situations: Migrating a computed NestingSingle to NestingGroup without clearing Computed; wanting provider-supplied defaults inside a group block.

Related errors


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