hashicorp/terraform · error

invalid value for %q: must be a number

Error message

invalid value for %q: must be a number

What it means

Thrown by SDKLikeDefaults.ApplyTo when an attribute typed cty.Number receives a string that is neither a valid integer (strconv.ParseInt) nor a valid float (strconv.ParseFloat). The code tries integer parsing first then falls back to float; failure of both produces this error.

Source

Thrown at internal/backend/backendbase/sdklike.go:280

				return cty.NilVal, fmt.Errorf("invalid value for %q: %s", attrName, err)
			}
			retAttrs[attrName] = cty.BoolVal(bv)
		case cty.Number:
			if rawStr == "" {
				rawStr = "0"
			}

			// This case is a little trickier because cty.Number could be
			// representing either an integer or a float, which each have
			// different interpretations in the legacy SDK. Therefore we'll
			// try integer first and use its result if successful, but then
			// try float as a fallback if not.
			if iv, err := strconv.ParseInt(rawStr, 0, 0); err == nil {
				retAttrs[attrName] = cty.NumberIntVal(iv)
			} else if fv, err := strconv.ParseFloat(rawStr, 64); err == nil {
				retAttrs[attrName] = cty.NumberFloatVal(fv)
			} else {
				return cty.NilVal, fmt.Errorf("invalid value for %q: must be a number", attrName)
			}
		default:
			panic("cannot apply environment variable defaults for " + ty.GoString())
		}
	}
	return cty.ObjectVal(retAttrs), nil
}

View on GitHub (pinned to c9def3e214)

Solutions

  1. Provide a plain numeric value without separators or units (e.g. 1024 or 10.5).
  2. If using hex/octal via ParseInt base 0, ensure the prefix (0x/0o/0b) is correct and digits are valid for that base.
  3. Set the number directly in the backend block as a native HCL number rather than via env var.

Example fix

# before
export SOME_BACKEND_NUM=1,024
# after
export SOME_BACKEND_NUM=1024
Defensive patterns

Strategy: validation

Validate before calling

func validNumberEnv(name string) bool {
    v := os.Getenv(name)
    if v == "" {
        return true
    }
    if _, err := strconv.ParseInt(v, 0, 0); err == nil {
        return true
    }
    _, err := strconv.ParseFloat(v, 64)
    return err == nil
}

Try / catch

val, err := defaults.ApplyTo(config)
if err != nil && strings.Contains(err.Error(), "must be a number") {
    return fmt.Errorf("a numeric backend argument got a non-numeric value: %w", err)
}

Prevention

When it happens

Trigger: A numeric backend attribute is supplied via config or environment variable with a non-numeric string (e.g. 'auto', 'unlimited', '1,024' with a comma, or '0x' with bad hex). Triggered during ApplyTo for any cty.Number attribute.

Common situations: Comma-separated thousands separators from locale-formatted numbers; trailing units like '5m'; copy-paste of human-readable values; env var left as a placeholder string.

Related errors


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