Question
Fixing Assembly Manifest Mismatch in C# (.NET): The Located Assembly's Manifest Definition Does Not Match the Assembly Reference
Question
I am trying to run unit tests in a C# Windows Forms application in Visual Studio 2005, and I get this error:
System.IO.FileLoadException: Could not load file or assembly 'Utility, Version=1.2.0.200, Culture=neutral, PublicKeyToken=764d581291d764f7' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
at x.Foo.FooGO()
at x.Foo.Foo2(string groupName_) in Foo.cs:line 123
at x.Foo.UnitTests.FooTests.TestFoo() in FooTests.cs:line 98
System.IO.FileLoadException: Could not load file or assembly 'Utility, Version=1.2.0.203, Culture=neutral, PublicKeyToken=764d581291d764f7' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)
In my project references, I only see a reference to Utility version 1.2.0.203. The older version appears to be 1.2.0.200.
How can I figure out what is still trying to reference the old version of this DLL?
Also, I do not think that I even have the old assembly on my hard drive. Is there a tool that can help search for this old versioned assembly or identify which assembly is requesting it?
Short Answer
By the end of this page, you will understand what an assembly manifest mismatch means in C#/.NET, why it happens even when your project references look correct, and how to trace the real source of an outdated DLL reference. You will also learn practical debugging tools such as Fusion Log Viewer, dependency inspection, and common fixes like cleaning output folders, updating dependent projects, and checking transitive references.
Concept
In .NET, an assembly reference is more than just a file name. It includes identity information such as:
- Assembly name
- Version
- Culture
- Public key token
When your code or one of its dependencies asks the runtime to load an assembly, .NET tries to find an assembly whose manifest exactly matches that identity.
A typical reference might look like this:
Utility, Version=1.2.0.203, Culture=neutral, PublicKeyToken=764d581291d764f7
If the runtime finds a file named Utility.dll but its embedded manifest says it is actually version 1.2.0.200, that is a mismatch. The runtime treats that as a different assembly and throws this error:
The located assembly's manifest definition does not match the assembly reference.
Why this happens
Common causes include:
- A project references a newer DLL, but the output folder still contains an older copy.
- Another dependent assembly was compiled against the old version.
- The Global Assembly Cache (GAC) contains a different version than expected.
- A unit test runner is loading assemblies from a different folder than you expect.
app.configor test configuration is missing a required binding redirect.- One machine has stale build artifacts or copied DLLs left over from older builds.
Why this matters
Assembly loading is fundamental in .NET applications:
Mental Model
Think of an assembly like a book with a title, edition number, language, and publisher stamp.
Even if two books are both called Utility, the runtime does not treat them as the same unless all identifying details match.
Utility= title1.2.0.203= editionneutral= languagePublicKeyToken=...= publisher stamp
If someone asks for Utility, edition 203, and you hand them Utility, edition 200, they may look similar, but the runtime says: this is not the exact book I asked for.
That is what a manifest mismatch means: the file was found, but its identity does not match the requested identity.
Syntax and Examples
In C#, you usually do not load referenced assemblies manually. The runtime does it for you based on compiled metadata.
Example of a normal reference
Suppose App.exe references Utility.dll:
using Utility;
class Program
{
static void Main()
{
Helper.DoWork();
}
}
At compile time, the application stores metadata saying which assembly identity it expects.
Example of the problem
Your app was compiled expecting:
Utility, Version=1.2.0.203
But at runtime, the folder contains:
Utility.dll --> actually version 1.2.0.200
Then .NET throws a FileLoadException.
How to inspect an assembly version in code
You can inspect what DLL was actually loaded:
using System;
using System.Reflection;
class Program
{
()
{
Assembly assembly = Assembly.Load();
Console.WriteLine(assembly.FullName);
}
}
Step by Step Execution
Consider this simplified situation:
TestProject.dll -> references App.dll
App.dll -> references Utility, Version=1.2.0.203
LegacyHelper.dll -> references Utility, Version=1.2.0.200
Your unit test calls code in App.dll, but App.dll also uses LegacyHelper.dll.
What happens step by step
-
The test runner starts loading
TestProject.dll. -
TestProject.dllloadsApp.dll. -
App.dllbegins executing code. -
During execution,
LegacyHelper.dllis loaded. -
LegacyHelper.dllasks for:Utility, Version=1.2.0.200 -
The runtime searches for a matching
Utility.dll. -
It finds
Utility.dll, but that file is actually version .
Real World Use Cases
Assembly version debugging appears in many real situations:
Unit test failures
A test project may compile fine, but the test runner loads old DLLs from a previous build directory.
Shared internal libraries
A company updates Utility.dll, but one older library still references the previous version.
Desktop application deployment
A Windows Forms or WPF app is deployed with the wrong DLL copy in its installation folder.
Plugin systems
A plugin built against one version of a shared assembly fails when loaded into a host using another version.
CI/CD build servers
A build agent may keep stale artifacts between builds, causing one machine to fail while another works.
GAC-related enterprise apps
A strongly named assembly in the GAC can override what developers expect from local output folders.
Real Codebase Usage
In real projects, developers usually handle assembly version issues with a few standard patterns.
1. Clean output before diagnosing
A common first step is to remove stale build artifacts:
- delete
bin/ - delete
obj/ - rebuild all projects
This is especially important in older .NET Framework solutions.
2. Check transitive dependencies
If A references B, and B references an old Utility.dll, then A may fail even though its own reference is correct.
Developers inspect all dependent assemblies, not just the main project.
3. Use guard-style diagnostics
In startup or test bootstrap code, developers sometimes log loaded assemblies:
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
Console.WriteLine(assembly.FullName);
}
This helps reveal which version was actually loaded.
4. Centralize dependency updates
In multi-project solutions, developers update shared dependencies everywhere before rebuilding.
5. Use configuration when version redirection is valid
Common Mistakes
1. Only checking the main project's references
Beginners often look at just one project's References node and assume everything is correct.
But the old reference may exist in:
- another project in the solution
- a third-party DLL
- a test helper assembly
- a plugin
2. Forgetting stale bin and obj folders
Broken build outputs can survive after reference changes.
Broken situation
- Project reference updated to
1.2.0.203 bin\Debug\Utility.dllstill contains1.2.0.200
Fix
Delete output folders manually and rebuild.
3. Ignoring the GAC
If the assembly is strongly named, the runtime may load it from the GAC.
A machine can have an old version installed even when the local file system looks clean.
4. Searching by file name only
Two DLLs can share the same file name but have different assembly identities.
Always inspect the embedded version and public key token, not just the file name.
5. Assuming the missing version must physically exist somewhere
Sometimes the runtime error mentions an old version because a compiled assembly requests it. The old DLL file does not need to be present for the error to occur.
6. Adding random copies of DLLs to fix it
Comparisons
| Concept | What it means | Typical symptom | Common fix |
|---|---|---|---|
| Assembly not found | .NET cannot locate the DLL at all | FileNotFoundException | Add/copy the correct DLL, fix probing path |
| Manifest mismatch | DLL was found, but identity does not match | FileLoadException with manifest definition mismatch | Update references, clean outputs, binding redirect, rebuild dependencies |
| Bad image format | DLL exists but is not valid for the process architecture | BadImageFormatException | Match x86/x64/AnyCPU |
| Compile-time reference error | Project cannot compile due to missing reference | Build error in Visual Studio | Fix project/package references |
Reference vs actual file
Cheat Sheet
Quick diagnosis checklist
- Check the exact assembly name, version, and public key token in the error.
- Delete all
binandobjfolders. - Rebuild the full solution.
- Use Fusion Log Viewer (
fuslogvw.exe). - Inspect dependent DLLs for old references.
- Check the GAC if the assembly is strongly named.
- Verify test runner config and output folder.
- Add a binding redirect if appropriate for .NET Framework.
Important rule
A .NET assembly reference is based on:
Name + Version + Culture + PublicKeyToken
A matching file name alone is not enough.
Common tools
fuslogvw.exe— assembly bind loggingildasm.exe— inspect assembly metadata- dotPeek / ILSpy — inspect references in DLLs
- Windows file search / command line search — find duplicate DLLs
gacutil— inspect GAC entries
Useful commands and actions
Manually clean outputs
Delete bin\ and obj\ folders in every project
Log loaded assemblies in code
FAQ
What does "manifest definition does not match the assembly reference" mean?
It means .NET found a DLL file, but the assembly identity inside that file does not match the version or strong name that was requested.
Why do I see an old version when my references show only the new one?
Because another dependency may still reference the old version, or a stale DLL may still exist in the output folder, test host folder, or GAC.
How do I find which assembly is requesting the old DLL version?
Use Fusion Log Viewer (fuslogvw.exe). It shows the bind request and often reveals the assembly that triggered it.
Can this happen even if the old DLL is not on my machine?
Yes. The error can happen simply because a compiled assembly requests the old version. The old DLL does not have to exist for the request to appear in the error.
Should I just copy the new DLL into the output folder?
Only if you know the requesting assembly expects that exact version or a binding redirect is in place. Randomly copying files often hides the real dependency issue.
Can binding redirects fix this?
Often yes in .NET Framework applications, if the newer assembly is compatible and the application or test host uses the correct config file.
Does the GAC matter here?
Yes. For strongly named assemblies, the GAC can affect what version the runtime loads.
Why does this happen more often in unit tests?
Test runners often load assemblies from separate folders and may use different config files from your main application.
Mini Project
Description
Create a small diagnostic console program that lists all currently loaded assemblies and attempts to load a target assembly by name. This project helps you understand how .NET identifies assemblies and gives you a practical way to inspect versions during debugging.
Goal
Build a simple assembly inspection tool that shows assembly full names and helps verify which version of a DLL is being loaded.
Requirements
- Create a C# console application.
- Print all assemblies currently loaded in the current AppDomain.
- Attempt to load an assembly by a simple name such as
Utility. - Display the assembly full name if loading succeeds.
- Catch and print assembly loading exceptions clearly.
Keep learning
Related questions
AddTransient vs AddScoped vs AddSingleton in ASP.NET Core Dependency Injection
Learn the differences between AddTransient, AddScoped, and AddSingleton in ASP.NET Core DI with examples and practical usage.
Best Way to Repeat a Character in C#: Building Repeated Strings Efficiently
Learn the best way to repeat a character in C#, compare StringBuilder, string concatenation, and simpler built-in options.
C# Array Initialization Syntaxes Explained
Learn all common C# array initialization syntaxes with examples, rules, comparisons, and mistakes beginners often make.