System.Threading.ThreadAbortException

.NET Exception Handling – System.BadImageFormatException

Today, as we continue along through our .NET Exception Handling series, we’re going to take a look at the System.BadImageFormatException. System.BadImageFormatException has nothing to do with gifs or jpgs, but instead, occurs when a .NET application attempts to load a dynamic link library (.dll) or executable (.exe) that doesn’t match the proper format that the current common language runtime (CLR) expects.

Throughout this article we’ll see exactly where System.BadImageFormatException sits within the .NET exception hierarchy and look at a few potential causes of System.BadImageFormatExceptions, so let’s get to it!

The Technical Rundown

When Should You Use It?

As previously mentioned, a System.BadImageFormatException occurs in very specific circumstances: When .NET attempts to make use of a .dll or .exe that is, in some way, incompatible with the current common language runtime. What qualifies as an “incompatible common language runtime” can vary somewhat, but typically this means either the .NET version (1.1, 2.0, etc) OR the CPU type (32-bit vs 64-bit) of the various compiled assemblies do not match.

Ultimately, System.BadImageFormatExceptions are an indication of incompatible versioning. For many modern software applications, major versions of often include breaking compatibility issues, preventing backward compatibility with some aspects of previous versions. .NET assemblies (.dlls or .exes) are much the same, and attempting to make use of two different types of assemblies that contain incompatibilities will often generate a System.BadImageFormatException.

To illustrate, we’ll go through a few different examples. I’ve included the full code example below for reference, after which we’ll explore the specifics in more detail:

The first (and arguably most common) way to raise a System.BadImageFormatException is when attempting to make use of an unmanaged assembly, as if it were an assembly created with the .NET Framework. Unmanaged assemblies are assemblies that have been generated from code that is not handled and compiled by the common language runtime of .NET. This includes many older applications and assemblies, particularly those created for 32-bit systems.

As an example, here we’re trying to load an unmanaged assembly — specifically the well-known notepad.exe assembly that resides in our Windows/System32 directory:

.NET is not to pleased with this, since notepad.exe is not managed (wasn’t compiled using .NET), and thus throws a System.BadImageFormatException:

Another way we might throw a System.BadImageFormatException is when trying to load an assembly that was compiled using a different CPU type than what we’re executing .NET on currently.

For example, throughout many of our code snippets we’ve been making use of our simple Utility namespace that contains the Logging class, making it a bit easier to output log information during debugging and testing. By default, our Utility.dll is compiled as a 64-bit assembly. However, if we switch our current CPU configuration to execute as an x86 (32-bit) CPU, we run into some trouble:

When attempting to load our Utility.dll assembly, which is 64-bit, while compiling our current code as 32-bit, .NET throws a System.BadImageFormatException, informing us these formats are mismatched:

Lastly, we also run into trouble if we attempt to load an assembly that was compiled using a much older version of .NET (such as .NET 1.1):

In cases like the one above, the System.BadImageFormatException will often be thrown at compile-time, rather than at runtime, since the .NET compiler recognizes the incompatibility before attempting to execute any of the code in the first place.

To get the most out of your own applications and to fully manage any and all .NET Exceptions, check out the Airbrake .NET Bug Handler, offering real-time alerts and instantaneous insight into what went wrong with your .NET code, along with built-in support for a variety of popular development integrations including: JIRA, GitHub, Bitbucket, and much more.