{"record":{"id":"1795bea62768c5d4","repo":"hashicorp/nomad","slug":"root-key-uuid-is-required","errorCode":null,"errorMessage":"root key UUID is required","messagePattern":"root key UUID is required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/structs/keyring.go","lineNumber":402,"sourceCode":"// variables or workload identities.\nfunc (rkm *RootKeyMeta) IsInactive() bool {\n\treturn rkm.State == RootKeyStateInactive || rkm.State == RootKeyStateDeprecated\n}\n\nfunc (rkm *RootKeyMeta) Copy() *RootKeyMeta {\n\tif rkm == nil {\n\t\treturn nil\n\t}\n\tout := *rkm\n\treturn &out\n}\n\nfunc (rkm *RootKeyMeta) Validate() error {\n\tif rkm == nil {\n\t\treturn fmt.Errorf(\"root key metadata is required\")\n\t}\n\tif rkm.KeyID == \"\" || !helper.IsUUID(rkm.KeyID) {\n\t\treturn fmt.Errorf(\"root key UUID is required\")\n\t}\n\tif rkm.Algorithm == \"\" {\n\t\treturn fmt.Errorf(\"root key algorithm is required\")\n\t}\n\tswitch rkm.State {\n\tcase RootKeyStateInactive, RootKeyStateActive,\n\t\tRootKeyStateRekeying, RootKeyStateDeprecated, RootKeyStatePrepublished:\n\tdefault:\n\t\treturn fmt.Errorf(\"root key state %q is invalid\", rkm.State)\n\t}\n\treturn nil\n}\n\n// KeyEncryptionKeyWrapper is a flattened version of the WrappedRootKeys struct\n// that gets serialized to disk for a keyset when using the legacy on-disk\n// keystore with the AEAD KMS wrapper. This struct includes the server-specific\n// key-wrapping key (KEK). This struct should never be sent over RPC or written\n// to Raft.","sourceCodeStart":384,"sourceCodeEnd":420,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/structs/keyring.go#L384-L420","documentation":"RootKeyMeta.Validate requires the KeyID field to be a non-empty, well-formed UUID (checked via helper.IsUUID). Root keys are identified by this UUID throughout the keyring, state store, and wrapped-key material, so an absent or malformed ID is rejected.","triggerScenarios":"Creating or upserting a root key whose KeyID is \"\" or not a canonical UUID (e.g. \"my-key\", \"1234\", or a UUID with wrong formatting/length).","commonSituations":"Generating keys manually with custom IDs instead of UUIDs; truncating or reformatting UUIDs when copying between systems; client-side key creation that forgot to call the ID generator.","solutions":["Generate a proper UUID for KeyID, e.g. via helper.GenerateUUID() or uuid.New().","Ensure the ID string is a canonical 8-4-4-4-12 hex UUID before submitting.","If the key already exists, look it up by its existing UUID rather than inventing a new one."],"exampleFix":"// before\nmeta := &structs.RootKeyMeta{KeyID: \"prod-key-1\"}\n// after\nmeta := &structs.RootKeyMeta{KeyID: helper.GenerateUUID()}","handlingStrategy":"validation","validationCode":"if meta.KeyID == \"\" || !helper.IsUUID(meta.KeyID) {\n    return fmt.Errorf(\"KeyID must be a valid UUID, got %q\", meta.KeyID)\n}","typeGuard":null,"tryCatchPattern":"if err := meta.Validate(); err != nil {\n    if strings.Contains(err.Error(), \"root key UUID is required\") {\n        meta.KeyID = helper.GenerateUUID()\n        err = meta.Validate()\n    }\n    return err\n}","preventionTips":["Generate key IDs only with helper.GenerateUUID() or uuid.New()","Never hand-write UUIDs in scripts; capture them from keyring list output","Store and reference keys by the server-issued UUID"],"tags":["nomad","keyring","root-key","uuid-validation"],"backgroundTag":"missing-root-key-metadata","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}