{"record":{"id":"aa4cfa6011827535","repo":"hashicorp/terraform","slug":"must-use-lowercase-hex-digits","errorCode":null,"errorMessage":"must use lowercase hex digits","messagePattern":"must use lowercase hex digits","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/addrs/resource.go","lineNumber":623,"sourceCode":"var deposedKeyRand = rand.New(rand.NewSource(time.Now().UnixNano()))\n\n// NewDeposedKey generates a pseudo-random deposed key. Because of the short\n// length of these keys, uniqueness is not a natural consequence and so the\n// caller should test to see if the generated key is already in use and generate\n// another if so, until a unique key is found.\nfunc NewDeposedKey() DeposedKey {\n\tv := deposedKeyRand.Uint32()\n\treturn DeposedKey(fmt.Sprintf(\"%08x\", v))\n}\n\n// ParseDeposedKey parses a string that is expected to be a deposed key,\n// returning an error if it doesn't conform to the expected syntax.\nfunc ParseDeposedKey(raw string) (DeposedKey, error) {\n\tif len(raw) != 8 {\n\t\treturn \"00000000\", fmt.Errorf(\"must be eight hexadecimal digits\")\n\t}\n\tif raw != strings.ToLower(raw) {\n\t\treturn \"00000000\", fmt.Errorf(\"must use lowercase hex digits\")\n\t}\n\t_, err := hex.DecodeString(raw)\n\tif err != nil {\n\t\treturn \"00000000\", fmt.Errorf(\"must be eight hexadecimal digits\")\n\t}\n\treturn DeposedKey(raw), nil\n}\n\nfunc (k DeposedKey) String() string {\n\treturn string(k)\n}\n\nfunc (k DeposedKey) GoString() string {\n\tks := string(k)\n\tswitch {\n\tcase ks == \"\":\n\t\treturn \"states.NotDeposed\"\n\tdefault:","sourceCodeStart":605,"sourceCodeEnd":641,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/addrs/resource.go#L605-L641","documentation":"Returned by ParseDeposedKey when the raw string equals itself lowercased, i.e. it contains one or more uppercase characters. DeposedKey is canonicalized to lowercase hex (matching NewDeposedKey's %08x). This check runs after the length check and before hex decoding.","triggerScenarios":"Returned at internal/addrs/resource.go:623 when raw != strings.ToLower(raw), inside ParseDeposedKey. Same callers as error 113 (stackplan proto parsing, stackstate key parsing).","commonSituations":"A deposed key sourced from a system that uppercased the hex (e.g. some proto/JSON tooling, or a user pasted UPPERCASE). An external integration that did not normalize case. Hand-constructed state with `DEADBEEF` instead of `deadbeef`.","solutions":["Normalize the key to lowercase before parsing: raw = strings.ToLower(raw) (only after confirming it is otherwise valid hex).","Fix the producing side to emit lowercase hex (%08x / %x) for deposed keys.","Repair the offending state/plan entry to the lowercase form."],"exampleFix":"// normalize before parse\nraw := strings.TrimSpace(input)\nraw = strings.ToLower(raw)\nkey, err := addrs.ParseDeposedKey(raw)","handlingStrategy":"validation","validationCode":"raw = strings.ToLower(strings.TrimSpace(raw))\nif raw != strings.ToLower(raw) {\n    return errors.New(\"deposed key must be lowercase\")\n}","typeGuard":"func isDeposedKeyCaseError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"must use lowercase hex digits\")\n}","tryCatchPattern":"k, err := addrs.ParseDeposedKey(raw)\nif err != nil && strings.Contains(err.Error(), \"lowercase\") {\n    k, err = addrs.ParseDeposedKey(strings.ToLower(raw))\n}","preventionTips":["Emit deposed keys with %08x (always lowercase).","Lowercase external input before parsing.","Add a unit test asserting lowercase output from NewDeposedKey."],"tags":["deposed-key","state","validation","normalization"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}