hashicorp/terraform · error

must use lowercase hex digits

Error message

must use lowercase hex digits

What it means

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.

Source

Thrown at internal/addrs/resource.go:623

var deposedKeyRand = rand.New(rand.NewSource(time.Now().UnixNano()))

// NewDeposedKey generates a pseudo-random deposed key. Because of the short
// length of these keys, uniqueness is not a natural consequence and so the
// caller should test to see if the generated key is already in use and generate
// another if so, until a unique key is found.
func NewDeposedKey() DeposedKey {
	v := deposedKeyRand.Uint32()
	return DeposedKey(fmt.Sprintf("%08x", v))
}

// ParseDeposedKey parses a string that is expected to be a deposed key,
// returning an error if it doesn't conform to the expected syntax.
func ParseDeposedKey(raw string) (DeposedKey, error) {
	if len(raw) != 8 {
		return "00000000", fmt.Errorf("must be eight hexadecimal digits")
	}
	if raw != strings.ToLower(raw) {
		return "00000000", fmt.Errorf("must use lowercase hex digits")
	}
	_, err := hex.DecodeString(raw)
	if err != nil {
		return "00000000", fmt.Errorf("must be eight hexadecimal digits")
	}
	return DeposedKey(raw), nil
}

func (k DeposedKey) String() string {
	return string(k)
}

func (k DeposedKey) GoString() string {
	ks := string(k)
	switch {
	case ks == "":
		return "states.NotDeposed"
	default:

View on GitHub (pinned to c9def3e214)

Solutions

  1. Normalize the key to lowercase before parsing: raw = strings.ToLower(raw) (only after confirming it is otherwise valid hex).
  2. Fix the producing side to emit lowercase hex (%08x / %x) for deposed keys.
  3. Repair the offending state/plan entry to the lowercase form.

Example fix

// normalize before parse
raw := strings.TrimSpace(input)
raw = strings.ToLower(raw)
key, err := addrs.ParseDeposedKey(raw)
Defensive patterns

Strategy: validation

Validate before calling

raw = strings.ToLower(strings.TrimSpace(raw))
if raw != strings.ToLower(raw) {
    return errors.New("deposed key must be lowercase")
}

Type guard

func isDeposedKeyCaseError(err error) bool {
    return err != nil && strings.Contains(err.Error(), "must use lowercase hex digits")
}

Try / catch

k, err := addrs.ParseDeposedKey(raw)
if err != nil && strings.Contains(err.Error(), "lowercase") {
    k, err = addrs.ParseDeposedKey(strings.ToLower(raw))
}

Prevention

When it happens

Trigger: 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).

Common situations: 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`.

Related errors


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/aa4cfa6011827535. Report an issue: GitHub.