gohugoio/hugo · error

integer overflow: %q

Error message

integer overflow: %q

What it means

When a numeric literal in a template parses as a float but contains none of '.', 'e', 'E', 'p', 'P' (i.e. it looks like an integer), the parser treats it as an integer too large to fit in int64/uint64 and rejects it as an overflow. See node.go:692-699.

Source

Thrown at tpl/internal/go_templates/texttemplate/parse/node.go:698

		if i == 0 {
			n.IsUint = true // in case of -0.
			n.Uint64 = u
		}
	}
	// If an integer extraction succeeded, promote the float.
	if n.IsInt {
		n.IsFloat = true
		n.Float64 = float64(n.Int64)
	} else if n.IsUint {
		n.IsFloat = true
		n.Float64 = float64(n.Uint64)
	} else {
		f, err := strconv.ParseFloat(text, 64)
		if err == nil {
			// If we parsed it as a float but it looks like an integer,
			// it's a huge number too large to fit in an int. Reject it.
			if !strings.ContainsAny(text, ".eEpP") {
				return nil, fmt.Errorf("integer overflow: %q", text)
			}
			n.IsFloat = true
			n.Float64 = f
			// If a floating-point extraction succeeded, extract the int if needed.
			if !n.IsInt && float64(int64(f)) == f {
				n.IsInt = true
				n.Int64 = int64(f)
			}
			if !n.IsUint && float64(uint64(f)) == f {
				n.IsUint = true
				n.Uint64 = uint64(f)
			}
		}
	}
	if !n.IsInt && !n.IsUint && !n.IsFloat {
		return nil, fmt.Errorf("illegal number syntax: %q", text)
	}
	return n, nil

View on GitHub (pinned to 52c9bd7908)

Solutions

  1. Quote the value as a string and handle it as text in the template.
  2. Express the number with scientific notation using an exponent character (e.g. 1e21) so it is treated as a float.
  3. Compute or pass the value from Go as typed data instead of an inline literal.

Example fix

// before
{{ 999999999999999999999 }}

// after
{{ "999999999999999999999" }}
Defensive patterns

Strategy: validation

Validate before calling

// Reject oversized integer literals before they reach the parser.
func safeIntLiteral(s string) (any, error) {
    if _, err := strconv.ParseInt(s, 0, 64); err == nil { return s, nil }
    if _, err := strconv.ParseUint(s, 0, 64); err == nil { return s, nil }
    if strings.ContainsAny(s, ".eEpP") { return s, nil }
    return nil, fmt.Errorf("integer too large; pass as string")
}

Try / catch

if _, err := template.New("t").Parse(body); err != nil { return err }

Prevention

When it happens

Trigger: A template literal like {{ 999999999999999999999 }} whose magnitude exceeds 64-bit integer range.

Common situations: Hardcoding huge IDs, timestamps, or hashes directly in templates; code-generated templates inserting oversized numeric tokens.

Related errors


AI-assisted analysis of gohugoio/hugo@52c9bd7908 (2026-08-09). Data as JSON: /api/errors/8ff057ccf537f0b7. Report an issue: GitHub.