System.OverflowException

An OverflowException is thrown when a number is too large or too small for the type it has to fit in. It happens in checked arithmetic, when you convert between numeric types, and when you parse a number from text. The message depends on the operation, for example Value was either too large or too small for an Int32.

Integer arithmetic is unchecked by default in C#, so int.MaxValue + 1 silently wraps around to a negative number. An OverflowException means that something in your code asked for the check, or that a method did.

Minimum version: >= 1.1 >= Core 1.0

Statistics

32
elmah.io logo 19

Common causes

The value is outside the range of the type. These are the usual ways to get there.

Parsing a number that is too large

int.Parse throws an OverflowException when the text is a valid number, but not one that fits in an int. The range of an int is about plus or minus 2.1 billion.

var quantity = int.Parse("99999999999");   // OverflowException

Use a larger type, or TryParse to handle values that do not fit:

if (int.TryParse("99999999999", out var quantity))
{
    Console.WriteLine(quantity);
}
else if (long.TryParse("99999999999", out var big))
{
    Console.WriteLine($"{big} does not fit in an int.");
}

The Convert methods check the range. A value that does not fit in a byte, which holds 0 to 255, throws.

var percent = 300;
var small = Convert.ToByte(percent);   // OverflowException

Check the range, or clamp the value:

var percent = 300;
var small = (byte)Math.Clamp(percent, 0, 255);

Inside a checked block or expression, an operation that overflows throws. The same happens when the project has the checked arithmetic compiler option turned on.

var quantity = int.MaxValue;
var total = checked(quantity + 1);   // OverflowException

Do the calculation in a larger type:

var quantity = int.MaxValue;
var total = (long)quantity + 1;

Math.Abs(int.MinValue) has no result, because the positive number is one more than an int can hold.

var value = int.MinValue;
var absolute = Math.Abs(value);   // OverflowException

Calculate with a long:

var value = int.MinValue;
var absolute = Math.Abs((long)value);

How to fix it and prevent it

Choose a type with enough room

Use long for counters and totals that can grow large, and decimal for money. BigInteger has no upper limit when you need it.

long total = 0;

foreach (var amount in new[] { int.MaxValue, int.MaxValue })
{
    total += amount;
}

Numbers from users and files can be anything. TryParse returns false for text that is not a number and for numbers that do not fit, without an exception.

var text = "300";

if (byte.TryParse(text, out var value))
{
    Console.WriteLine(value);
}

Unchecked arithmetic gives silent wrong results. Wrap calculations that must be right in checked, and handle the exception where you can report it.

try
{
    var total = checked(Quantity() + int.MaxValue);
}
catch (OverflowException)
{
    Console.WriteLine("The order total is too large.");
}

static int Quantity() => 1;

How to find the overflowing value

The first line in your own code is the call that failed. For parsing, the trace goes through the framework before it reaches you:

System.OverflowException: Value was either too large or too small for an Int32.
   at System.Number.ThrowOverflowException[TInteger]()
   at System.Int32.Parse(String s)
   at Shop.Services.OrderParser.ParseQuantity(String text) in C:\src\Shop\Services\OrderParser.cs:line 11
   at Program.<Main>$(String[] args) in C:\src\Shop\Program.cs:line 4

The message tells you the target type, here Int32. The line in OrderParser.cs shows the call, and the line below it shows who passed the text. The exception does not contain the value, so log the input where you parse it.

Should you catch it?

Usually not around calculations. If a number can be too large, use a bigger type or check the range before you convert.

For input from users and files, use TryParse and report invalid values. Catch an OverflowException only where you cannot avoid it, and log the input that caused it.

Find OverflowException before your users do

elmah.io logs every unhandled exception in your .NET application with its stack trace and request details, groups identical errors and notifies you when a new one appears.

Start free trial
Free 21-day trial No credit card required

Related exceptions

Frequently asked questions

Why does int.MaxValue + 1 not throw?

Integer arithmetic is unchecked by default in C#. The value wraps around to int.MinValue. Use checked to get an OverflowException instead.

A FormatException means the text is not a number. An OverflowException means it is a number, but it does not fit in the type.

Not in arithmetic. A double that is too large becomes Infinity. Converting it to an integer type in a checked context, or with Convert, does throw.

Compare the value to the range of the target type, use Math.Clamp to limit it, or use a larger type.

Let your AI agent track it down

Connect Claude Code, Cursor, VS Code or Visual Studio to the elmah.io MCP server and ask your agent to look into OverflowException for you. For example:

AI chat
Find the most frequent OverflowException in my production log and show me the line that throws it.

The agent reads the stack trace and request details from elmah.io, finds the code in your repository and proposes a fix. In Claude Code, add the server with one command:

claude mcp add --transport http --client-id claudecode elmahio https://mcp.elmah.io/mcp

The MCP server is included on every plan and is currently in beta. Set up the MCP server.

Further reading

YouTube videos

Answers from Stack Overflow

    [Browsable(false)]
    [EditorBrowsable(EditorBrowsableState.Never)]
    [Obsolete("Property '" + nameof(Duration) + "' should be used instead.")]        
    public long DurationTicks { get; set; }

    [NotMapped]
    public TimeSpan Duration
    {
#pragma warning disable 618
      get { return new TimeSpan(DurationTicks); }
      set { DurationTicks = value.Ticks; }
#pragma warning restore 618
    }

Update

This is now achievable since EF Core 2.1, using Value Conversion.

builder.Entity<Stage>()
    .Property(s => s.Span)
    .HasConversion(new TimeSpanToTicksConverter()); // or TimeSpanToStringConverter

By Shimmy Weitzhandler. Read the original answer on Stack Overflow.

The current implementation of System.Array uses Int32 for all its internal counters etc, so the theoretical maximum number of elements is Int32.MaxValue.

There's also a 2GB max-size-per-object limit imposed by the Microsoft CLR.

A good discussion and workaround here...

And a few related, not-quite-duplicate, questions and answers here...

By LukeH. Read the original answer on Stack Overflow.

Because the specification says so in section 7.6.10.4:

Each expression in the expression list must be of type int, uint, long, or ulong, or implicitly convertible to one or more of these types.

This is most likely to easily allow creation of arrays larger than 2 GiB, even though they are not supported yet (but will be without a language change once the CLR makes such a change). Mono does support this, however and .NET 4.5 apparently will allow larger arrays too.

Regarding array length being an int by the way: There is also LongLength, returning a long. This was in .NET 1.1 and probably a future-proofing change.

By Joey. Read the original answer on Stack Overflow.

This corner-case is very specifically addressed in the compiler. Most relevant comments and code in the Roslyn source:

// Although remainder and division always overflow at runtime with arguments int.MinValue/long.MinValue and -1     
// (regardless of checked context) the constant folding behavior is different.     
// Remainder never overflows at compile time while division does.    
newValue = FoldNeverOverflowBinaryOperators(kind, valueLeft, valueRight);

And:

// MinValue % -1 always overflows at runtime but never at compile time    
case BinaryOperatorKind.IntRemainder:
    return (valueRight.Int32Value != -1) ? valueLeft.Int32Value % valueRight.Int32Value : 0;
case BinaryOperatorKind.LongRemainder:
    return (valueRight.Int64Value != -1) ? valueLeft.Int64Value % valueRight.Int64Value : 0;

Also the behavior of the legacy C++ version of compiler, going all the way back to version 1. From the SSCLI v1.0 distribution, clr/src/csharp/sccomp/fncbind.cpp source file:

case EK_MOD:
    // if we don't check this, then 0x80000000 % -1 will cause an exception...
    if (d2 == -1) {
        result = 0;
    } else {
        result = d1 % d2;
    }
    break;

So conclusion to draw that this was not overlooked or forgotten about, at least by the programmers that worked on the compiler, it could perhaps be qualified as insufficiently precise language in the C# language specification. More about the runtime trouble caused by this killer poke in this post.

By Hans Passant. Read the original answer on Stack Overflow.

Now EF Core has built-in ticks <=> TimeSpan conversion. All you have to do is:

builder.Property(p => p.SomeTimeSpanProperty)
    .HasConversion<long>();

No need to instantiate a new TimeSpanToTicksConverter or anything. Just specify the type long as the generic argument, and you're done.

For more info see EF Core Built-in Value Converters

By Arad. Read the original answer on Stack Overflow.