hashicorp/terraform · error

error unmarshaling lock info: %s

Error message

error unmarshaling lock info: %s

What it means

Raised by getLockInfo() (consul/client.go:356) when the JSON blob stored at <lockPath>/.lockinfo cannot be unmarshaled into statemgr.LockInfo. The lock-info key is meant to be the JSON-serialized LockInfo written by putLockInfo; corruption or schema drift makes unmarshal fail and the wrapped error is surfaced.

Source

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

	}, nil)

	return err
}

func (c *RemoteClient) getLockInfo() (*statemgr.LockInfo, error) {
	path := c.lockPath() + lockInfoSuffix
	pair, _, err := c.Client.KV().Get(path, nil)
	if err != nil {
		return nil, err
	}
	if pair == nil {
		return nil, nil
	}

	li := &statemgr.LockInfo{}
	err = json.Unmarshal(pair.Value, li)
	if err != nil {
		return nil, fmt.Errorf("error unmarshaling lock info: %s", err)
	}

	return li, nil
}

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.

View on GitHub (pinned to c9def3e214)

Solutions

  1. Read the raw value of <lockPath>/.lockinfo in Consul to see what was actually stored.
  2. If it is stale or corrupt, clear the lock with `terraform force-unlock <lock-id>` (the session ID).
  3. As a last resort, delete the .lockinfo KV and the matching .lock KV manually, then re-run.
  4. Standardize the terraform version across the team to avoid LockInfo schema drift.
Defensive patterns

Strategy: try-catch

Try / catch

// Gracefully handle corrupt lock info by clearing the stale lock
if _, err := client.getLockInfo(); err != nil {
    if strings.Contains(err.Error(), "error unmarshaling lock info") {
        // clear the corrupt .lockinfo and .lock KVs, then force-unlock
        clearConsulLock(client)
    }
}

Prevention

When it happens

Trigger: getLockInfo() reads pair.Value for the .lockinfo key and json.Unmarshal returns an error. Encountered when the value is truncated, non-JSON, or written by an incompatible terraform version with a different LockInfo schema.

Common situations: Manual edit/deletion of the .lockinfo KV; a crashed run left a partial write; mixing terraform versions where LockInfo fields differ; someone wrote arbitrary bytes to that key.

Related errors


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