OverflowError: Python int too large to convert to C long happens when a Python integer is passed to code that expects a fixed-size C long. Python integers can grow as large as memory allows, but many operating-system calls, binary formats, and C extensions still use bounded C integer types.
The fix is to identify the boundary before the conversion happens. On common 64-bit builds, a signed C long usually accepts values from -9223372036854775808 through 9223372036854775807. Code that receives larger numbers should reject them, store them as text, use a different binary format, or choose an API designed for arbitrary-size integers.
The official Python references for this topic are OverflowError, sys.maxsize, the array module, the struct module, and ctypes.
Start with the traceback. If the failing line calls array.array(), struct.pack(), a database driver, a C extension, or an operating-system wrapper, the problem is not Python math itself. The problem is the handoff from Python’s unbounded integer model into a bounded native slot.
Check The C Long Range
sys.maxsize is a practical upper bound for signed pointer-sized values on the running build. For a typical 64-bit Python, it matches the positive side of a signed C long range used by many interfaces.
import sys
long_min = -sys.maxsize - 1
long_max = sys.maxsize
samples = [0, long_max, long_max + 1]
for number in samples:
fits = long_min <= number <= long_max
print(number, fits)
This check gives a clear yes-or-no answer before calling a lower-level API. Do not wait for the conversion failure if you can validate the integer at the boundary.
On unusual platforms the native range can differ, so checking on the runtime that will execute the code is better than hard-coding a range from another machine.
Reproduce The Error With array
The array module stores compact C-style values. Type code "l" represents a signed C long, so a huge Python integer cannot always be stored there.
import array
import sys
items = [10, sys.maxsize, sys.maxsize + 1]
for number in items:
try:
stored = array.array("l", [number])
print(number, stored[0])
except OverflowError:
print(number, "outside C long")
This is close to the real failure many users see. The smaller values fit, while the value just above the platform limit is rejected.
If you need to keep very large integers, do not force them into an array("l"). Store them as decimal text, split them into limbs, or use a format that explicitly supports big integers.
Guard struct.pack Calls
The struct module writes binary records with fixed field sizes. Format code "l" is also a C long, so validate the integer before packing.
import struct
import sys
def pack_c_long(number):
lower = -sys.maxsize - 1
upper = sys.maxsize
if not lower <= number <= upper:
return None
return struct.pack("l", number)
for number in [7, 10**100]:
data = pack_c_long(number)
print(number, "packed" if data else "blocked")
The guard prevents an exception and gives the caller a chance to choose a different storage path. That is usually cleaner than letting a binary writer fail halfway through a larger export.
Use an explicit format such as "q" for a signed 64-bit field when the file format requires that exact width. Even then, the value must fit inside that width.
Validate Text Input Before Conversion
Large integers often arrive from form fields, CSV rows, JSON payloads, or command-line arguments. Convert the text once, then check the range before passing the integer onward.
import sys
def read_c_long(text):
number = int(text)
lower = -sys.maxsize - 1
upper = sys.maxsize
if number < lower or number > upper:
raise OverflowError("integer is outside the C long range")
return number
for text in ["123", "1000000000000000000000000000000"]:
try:
print(read_c_long(text))
except OverflowError as error:
print(error)
This pattern is useful at API edges. The caller receives a specific message tied to the accepted range instead of a broad low-level conversion error.
If the number is an identifier rather than a quantity for arithmetic, consider keeping it as text. Very large account IDs, hashes, and external keys often should not be converted to C numeric fields at all.
Do Not Rely On ctypes Wrapping
ctypes.c_long() can wrap or truncate oversized integers instead of raising the same error. That behavior is useful for low-level C work, but it is dangerous as a validation step.
import ctypes
for number in [123, 10**100]:
wrapped = ctypes.c_long(number).value
print(number == wrapped, wrapped)
The second result is not the original integer. If a C library needs a real C long, range-check first and pass only accepted values.
Silent wrapping can create worse bugs than an exception because the program keeps running with the wrong value. Treat it as a low-level conversion detail, not as proof that the input is safe.
Choose A Safe Storage Path
When the integer does not fit, choose a representation that matches the task. Pure Python math can keep using the large integer. A binary C field cannot. A database column, file format, or API should document its accepted range.
import sys
def storage_plan(number):
lower = -sys.maxsize - 1
upper = sys.maxsize
if lower <= number <= upper:
return "c_long"
return "decimal_text"
for number in [2026, 10**40]:
print(storage_plan(number), str(number)[:12])
This kind of small decision point keeps the conversion rule visible. It also makes tests easy: one case inside the range, one case outside it, and one negative boundary if your program accepts negative values.
In short, fix Python int too large to convert to C long by checking the value before it reaches a C-sized field. Use sys.maxsize as the runtime clue, validate array and struct inputs, avoid silent ctypes wrapping, and store oversized integers in a format that actually supports them.


