hashicorp/nomad · error

root key in use, cannot delete

Error message

root key in use, cannot delete

What it means

A root key that has already encrypted variables cannot be deleted, because that would make the variables undecryptable. The keyring Delete endpoint returns this error when IsRootKeyInUse reports the key was used and the request did not set Force.

Source

Thrown at nomad/keyring_endpoint.go:364

	if err != nil {
		return err
	}

	if rootKey == nil {
		return errors.New("root key not found")
	}

	if rootKey != nil && rootKey.IsActive() {
		return fmt.Errorf("active root key cannot be deleted - call rotate first")
	}

	// make sure the key was used to encrypt an existing variable
	rootKeyInUse, err := snap.IsRootKeyInUse(args.KeyID)
	if err != nil {
		return err
	}
	if rootKeyInUse && !args.Force {
		return errors.New("root key in use, cannot delete")
	}

	_, index, err = k.srv.raftApply(structs.WrappedRootKeysDeleteRequestType, args)
	if err != nil {
		return err
	}

	// remove the key from the keyring too
	k.encrypter.RemoveKey(args.KeyID)

	reply.Index = index
	return nil
}

// ListPublic signing keys used for workload identities. This RPC is used to
// back a JWKS endpoint.
//
// Unauthenticated because public keys are not sensitive.

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Rewrite variables with a different key (or re-encrypt via rotation), then delete the key.
  2. Pass `-force` (`nomad keyring remove -key-id <id> -force`) to delete anyway, acknowledging the affected variables cannot be decrypted.
  3. Rotate the root key first so new data uses the new key, then force-delete the old one if acceptable.

Example fix

// before
nomad keyring remove -key-id abc123

// after
nomad keyring remove -key-id abc123 -force
Defensive patterns

Strategy: try-catch

Validate before calling

// check usage before delete
inUse, err := client.Variables().List(nil) // inspect which keys variables reference
// or simply pass Force: true when old variables are expendable

Try / catch

if _, err := k.Delete(args); err != nil && strings.Contains(err.Error(), "root key in use") {
  // prompt user or set args.Force = true after acknowledging data loss
  args.Force = true
  return k.Delete(args)
}

Prevention

When it happens

Trigger: Calling `nomad keyring remove` on a key that was used to encrypt existing variables without passing `-force`.

Common situations: Rotating variables keys and pruning old ones while old variables still exist; routine cleanup hitting keys referenced by live variables.

Related errors


AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04). Data as JSON: /api/errors/f2234aa8961385a0. Report an issue: GitHub.