Ad Space — Top Banner

integer overflow (silent)

Go Programming Language

Severity: Moderate

What Does This Error Mean?

Integer overflow in Go happens when a calculation produces a number larger than the maximum value the integer type can hold. Unlike some languages, Go does NOT panic on integer overflow — the value silently wraps around to a small or negative number. For example, a maximum int8 value is 127. Adding 1 to it gives -128 instead of 128. This silent behavior makes overflow bugs hard to detect — the code keeps running but with wrong values.

Affected Models

  • Go 1.0 and later
  • All Go versions

Common Causes

  • Multiplying two large numbers that exceed the int64 maximum (about 9.2 quintillion)
  • Incrementing a counter that reaches the maximum value of its integer type
  • Adding user-supplied numbers without checking for overflow
  • Using small integer types (int8, int16) and performing arithmetic that exceeds their range
  • Converting a larger integer type to a smaller one without checking the value fits

How to Fix It

  1. Use a larger integer type. Most Go code uses int (which is 64-bit on 64-bit systems) or int64 explicitly for large numbers.

    int8 holds -128 to 127. int16 holds -32768 to 32767. int32 holds up to about 2 billion. int64 holds up to about 9.2 quintillion. Use the right size for your data.

  2. For very large numbers, use the math/big package: big.Int can hold arbitrarily large integers with no overflow.

    import 'math/big'; x := new(big.Int).SetInt64(9999999999999999999) — big.Int handles numbers of any size.

  3. Before a multiplication that might overflow, check whether it will: if a > math.MaxInt64/b — if true, the multiplication would overflow.

    For addition: check if a > math.MaxInt64-b. For subtraction: check if a < math.MinInt64+b. Always check before, not after.

  4. Use the math/bits package for overflow-safe arithmetic: bits.Add64, bits.Mul64 return a carry/overflow flag alongside the result.

    hi, lo := bits.Mul64(a, b) — if hi != 0, the multiplication overflowed 64 bits.

  5. When converting between integer types, check the value fits: if x > math.MaxInt8 || x < math.MinInt8 — the value cannot safely be converted to int8.

    Go silently truncates when converting larger to smaller integer types. Always bounds-check before narrowing conversions.

When to Call a Professional

Integer overflow is a logic bug that you can fix yourself. Decide whether you need a larger integer type, overflow checks, or the math/big package for arbitrary precision. For security-sensitive code (like cryptography or financial calculations), always add explicit overflow checks.

Frequently Asked Questions

Why does Go not panic on integer overflow?

Go follows the C language tradition for integer types — overflow wraps around silently. This is a design choice that prioritizes performance (no overflow checks on every arithmetic operation) over safety. In contrast, Rust detects overflow in debug builds and panics, but wraps silently in release builds. If you need overflow detection in Go, use the math/bits package or perform manual checks.

What is the maximum value of int in Go?

On 64-bit systems (which is almost all modern computers), int is 64 bits — maximum value about 9.2 × 10^18 (9,223,372,036,854,775,807). On 32-bit systems, int is 32 bits — maximum about 2.1 billion. For guaranteed sizes, use int64 or int32 explicitly rather than plain int. For the exact maximum, use math.MaxInt, math.MaxInt32, math.MaxInt64 from the math package.

How do I detect overflow that has already happened?

If the result has already wrapped around, you generally cannot detect it after the fact. That is why overflow must be checked BEFORE the operation, not after. For additions: if result < a (where a is positive and result should be larger), overflow occurred. For multiplications: if a != 0 && result/a != b, overflow occurred. But prevention with upfront checks is always better than detection after the fact.