System.ArrayTypeMismatchException

An ArrayTypeMismatchException is thrown when you store an element in an array and the element is not compatible with the actual type of the array. The message is Attempted to access an element as a type incompatible with the array.

It is caused by array covariance. An array of strings can be used as an array of objects, so the compiler allows you to assign any object to it, and the runtime checks the type of every assignment.

Minimum version: >= 1.1 >= Core 1.0

Statistics

37

Common causes

The array was created with one type and used through another. These are the usual ways.

Assigning through a covariant array

An array of a reference type converts implicitly to an array of its base type. Writing to it through the base type compiles, and fails when the element is not of the real type.

object[] values = new string[2];
values[0] = 42;   // ArrayTypeMismatchException

Create the array with the type you want to store, or use a list:

object[] values = new object[2];
values[0] = 42;

var list = new List<object> { 42, "text" };

A method that takes object[] accepts a string[] too. The method cannot know the actual array type, so a write can fail depending on what the caller passed.

public static class Catalog
{
    public static void Fill(object[] slots)
    {
        slots[0] = 42;   // ArrayTypeMismatchException when slots is a string[]
    }
}

Make the method generic, so the element type is the same for the array and the value:

public static class Catalog
{
    public static void Fill<T>(T[] slots, T value)
    {
        slots[0] = value;
    }
}

How to fix it and prevent it

Use List<T> or other generic collections

Generic collections are not covariant for writing, so the compiler stops the mistake. List<object> cannot be assigned from a List<string>.

IEnumerable<T> and IReadOnlyList<T> are covariant for reading, and have no way to write. A method that only reads from the elements can safely accept arrays of a derived type.

static void Print(IReadOnlyList<object> items)
{
    foreach (var item in items)
    {
        Console.WriteLine(item);
    }
}

A generic method that takes T[] and a T uses the real element type, so the write is always valid.

static void Set<T>(T[] array, int index, T value)
{
    array[index] = value;
}

How to find the mismatch

The stack trace points to the assignment:

System.ArrayTypeMismatchException: Attempted to access an element as a type incompatible with the array.
   at Shop.Services.Catalog.Fill(Object[] slots) in C:\src\Shop\Services\Catalog.cs:line 9
   at Program.<Main>$(String[] args) in C:\src\Shop\Program.cs:line 5

Line 9 of Catalog.cs stores an integer in an array that was created as string[] by the caller. The line below it shows where the array came from. Look for an array that was created with a more specific type than the code that uses it expects.

Should you catch it?

No. The exception means the code stores the wrong type in an array, which is a design problem. Change the code so the array and the element have the same type, or use a generic collection.

Find ArrayTypeMismatchException 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

What is array covariance?

It means that an array of a derived type, such as string[], can be assigned to a variable of an array of a base type, such as object[]. It was added to .NET before generics, and the runtime checks every write because of it.

Generic classes are invariant, so the compiler rejects the second case. That is safer, because a List<object> would accept values that a List<string> cannot hold.

No. Covariance only works for arrays of reference types. An int[] cannot be used as an object[].

Do not write to array parameters of a base type. Take a generic array, a list, or a read-only interface.

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 ArrayTypeMismatchException for you. For example:

AI chat
Find the most frequent ArrayTypeMismatchException 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

Okay, this really depends on a few oddities combined:

  • Even though in C# you can't cast a byte[] to an sbyte[] directly, the CLR allows it:

    var foo = new byte[] {246, 127};
    // This produces a warning at compile-time, and the C# compiler "optimizes"
    // to the constant "false"
    Console.WriteLine(foo is sbyte[]);
    
    object x = foo;
    // Using object fools the C# compiler into really consulting the CLR... which
    // allows the conversion, so this prints True
    Console.WriteLine(x is sbyte[]);
    
  • Cast<T>() optimizes such that if it thinks it doesn't need to do anything (via an is check like the above) it returns the original reference - so that's happening here.

  • ToList() delegates to the constructor of List<T> taking an IEnumerable<T>

  • That constructor is optimized for ICollection<T> to use CopyTo... and that's what's failing. Here's a version which has no method calls other than CopyTo:

    object bytes = new byte[] { 246, 127 };
    
    // This succeeds...
    ICollection<sbyte> list = (ICollection<sbyte>) bytes;
    
    sbyte[] array = new sbyte[2];
    
    list.CopyTo(array, 0);
    

Now if you use a Select at any point, you don't end up with an ICollection<T>, so it goes through the legitimate (for the CLR) byte/sbyte conversion for each element, rather than trying to use the array implementation of CopyTo.

By Jon Skeet. Read the original answer on Stack Overflow.

UPDATED WITH THE SOLUTION

Okay, this was very tricky. I have no idea how you manage to get this type of project. You might have upgraded your project type from an earlier version of ASP.NET MVC. Any way below is the answer.

In you Web.Config's runtime Assembly binding section, please add the below.

<dependentAssembly>
    <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
    <bindingRedirect oldVersion="1.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>

This should fix your problem.

By Spock. Read the original answer on Stack Overflow.

You can use .Select(e => (Test)e).

By Daniel A. White. Read the original answer on Stack Overflow.

You are trying to cast the array to int[] when it is a uint[]. That by itself is fine, since both int[] and uint[] are of type Array, and casting an Array object of type uint[] as an int[] (or vice versa) is allowed (for some reason).

The problem comes when you try to then convert it to a List. The method is trying to create a List of type int because that's the type you specified, but that's not what the type of the array actually is.

By Abion47. Read the original answer on Stack Overflow.

assembly.GetTypes() returns a RuntimeType[], but it uses array type covariance to disguise it as a Type[]. Per the docs for the Span constructor, an ArrayTypeMismatchException is thrown if T (which in this case is Type) does not match the runtime array type (which in this case is RuntimeType).

assembly.GetTypes().ToArray() on the other hand returns an actual Type[]: it will create a brand new array based on the declared type T, which is Type, so you get a true Type[] array and there is no mismatch -- T is Type and you're passing a true Type[] to the Span constructor.

ReadOnlySpan<T> does not have this constraint, since it is not possible to write an incompatible Type to a read-only RuntimeType[], so you can do this:

new ReadOnlySpan<Type>(assembly.GetTypes());

By Jeff. Read the original answer on Stack Overflow.