hashicorp/terraform · error

invalid value for : must be a number

Error message

invalid value for %q: must be a number

What it means

Thrown by SDKLikeDefaults.ApplyTo in the cty.Number case when neither strconv.ParseInt nor strconv.ParseFloat can interpret rawStr. As with error 122, the HCL value itself is already type-checked, so the offending value comes from an env var or Fallback. The integer parse uses base 0 (so 0x.. and 0.. are honored); the float parse is the fallback.

Solutions

  1. Provide a plain numeric value (e.g. 443, 86400, 2.5) in the env var or backend block.
  2. Strip units, quotes, and thousands separators from the value before exporting it.
  3. If the value should carry units, change the backend attribute to a string and parse it in your own Configure code instead of relying on the SDK-like number coercion.
  4. Verify the env var is not being overwritten by a CI template with a non-numeric default.

Example fix

# before
export GCS_REQUESTER_PAYS="yes"   # numeric attr -> must be a number
# after
export GCS_REQUESTER_PAYS="1"
Defensive patterns

Strategy: validation

Validate before calling

func numberEnvOk(name string) error {
    if v := os.Getenv(name); v != "" {
        if _, err1 := strconv.ParseInt(v, 0, 0); err1 != nil {
            if _, err2 := strconv.ParseFloat(v, 64); err2 != nil {
                return fmt.Errorf("env %s=%q is not a number", name, v)
            }
        }
    }
    return nil
}

Type guard

null

Try / catch

if _, err := defs.ApplyTo(cfg); err != nil {
    if strings.Contains(err.Error(), "must be a number") {
        return fmt.Errorf("a backend env var has a non-numeric value: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: A cty.Number attribute has EnvVars; the user sets that env var to something that is neither an integer nor a float. Examples: "10s", "5mb", "1,024" (comma), "3.14.15", "auto", or a value with surrounding text.

Common situations: Passing a duration or size with units to a numeric backend knob (e.g. a port number env var set to "port 443"), locale-specific number formats with a comma decimal separator, or an env var that resolved to a placeholder like '<unset>'.

Related errors


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

Appendix: 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 d32a084675)