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
- Populate args.KeyID with the root key ID before calling Get.
- List keys first (keyring list endpoint) to obtain a valid KeyID.
- 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
- Check shell/CI variables for the key ID before invoking the API.
- List keys first to obtain valid IDs programmatically.
- Trim and non-empty-check IDs parsed from URLs or user input.
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
- missing plugin ID
- missing plugin ID
- missing deployment ID
- missing parameterized job ID
- root key material is required
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/6a3d9233c35b181b.
Report an issue: GitHub.