hashicorp/nomad · error

root key ID is required

Error message

root key ID is required

What it means

The keyring Get endpoint requires a KeyID to look up. Since Get is a point-read of one root key, an empty KeyID cannot identify any key and is rejected up front after forwarding, before the blocking query is set up.

Source

Thrown at nomad/keyring_endpoint.go:277

}

// Get retrieves an existing key from the keyring, including both the
// key material and metadata. It is used only for replication.
func (k *Keyring) Get(args *structs.KeyringGetRootKeyRequest, reply *structs.KeyringGetRootKeyResponse) error {
	aclObj, err := k.srv.AuthenticateServerOnly(k.ctx, args)
	k.srv.MeasureRPCRate("keyring", structs.RateMetricRead, args)

	if err != nil || !aclObj.AllowServerOp() {
		return structs.ErrPermissionDenied
	}

	if done, err := k.srv.forward("Keyring.Get", args, args, reply); done {
		return err
	}
	defer metrics.MeasureSince([]string{"nomad", "keyring", "get"}, time.Now())

	if args.KeyID == "" {
		return fmt.Errorf("root key ID is required")
	}

	// Setup the blocking query
	opts := blockingOptions{
		queryOpts: &args.QueryOptions,
		queryMeta: &reply.QueryMeta,
		run: func(ws memdb.WatchSet, s *state.StateStore) error {

			snap, err := k.srv.fsm.State().Snapshot()
			if err != nil {
				return err
			}
			wrappedKey, err := snap.RootKeyByID(ws, args.KeyID)
			if err != nil {
				return err
			}
			if wrappedKey == nil {
				return k.srv.replySetIndex(state.TableRootKeys, &reply.QueryMeta)

View on GitHub (pinned to 482b49bf1a)

Solutions

  1. Populate args.KeyID with the root key ID before calling Get.
  2. List keys first (keyring list endpoint) to obtain a valid KeyID.
  3. Add a client-side check that KeyID is non-empty before issuing the RPC.

Example fix

// before
reply, err := client.Keyring().Get(&structs.KeyringGetRootKeyRequest{})
// after
if keyID == "" { return fmt.Errorf("keyID must be set") }
reply, err := client.Keyring().Get(&structs.KeyringGetRootKeyRequest{KeyID: keyID})
Defensive patterns

Strategy: validation

Validate before calling

if keyID == "" {
    return fmt.Errorf("cannot Get keyring key: keyID is empty")
}

Type guard

func keyIDProvided(req *structs.KeyringGetRootKeyRequest) bool {
    return req != nil && req.KeyID != ""
}

Try / catch

reply, err := client.Keyring().Get(req, nil)
if err != nil && strings.Contains(err.Error(), "root key ID is required") {
    return fmt.Errorf("caller bug: KeyID was empty; check %q source variable", idVar)
}

Prevention

When it happens

Trigger: Calling the Keyring.Get RPC (or GET /v1/kms/keys/<id>) with args.KeyID empty string — e.g. omitting the key ID in the URL path or passing an unset variable.

Common situations: A shell variable holding the key ID is empty/unset in a script; a UI or automation passes a nil-tenant placeholder; a wrapper function's argument is dropped.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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