You must install or update .NET to run this application. followed by
Framework: 'Microsoft.NETCore.App', version '8.0.0' means the app was built for
.NET 8 and the machine (here, a container) has only a newer runtime. Install the .NET 8
runtime there, or allow the app to roll forward to the newer major version.
For production, install the runtime the app targets, or move the app to the runtime you have.
For a quick test, set DOTNET_ROLL_FORWARD=Major or put
<RollForward>Major</RollForward> in the project file; both made the
same .NET 8 build run on .NET 10.
The error
You must install or update .NET to run this application.
App: /app/FixLab.dll
Architecture: x64
Framework: 'Microsoft.NETCore.App', version '8.0.0' (x64)
.NET location: /usr/share/dotnet/
The following frameworks were found:
10.0.10 at [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Why it happens
A framework-dependent build does not carry the runtime. Its
FixLab.runtimeconfig.json names the framework it needs, here
Microsoft.NETCore.App 8.0.0, and the host that starts the app looks for a
matching installed runtime. By default it will move up to a newer patch or minor version of
.NET 8, but never to another major version. The container had only the 10.0.10 runtime, so
the host listed what it found and stopped with exit code 150.
The SDK image is a common trap: mcr.microsoft.com/dotnet/sdk:10.0 builds .NET 8
projects without complaint, because the SDK can target older frameworks, but it ships only
the .NET 10 runtime. The same thing happens on a server that was upgraded to a new runtime
while an older app stayed on its old target.
The fix
docker run --rm --name fix4-net8 -e DOTNET_ROLL_FORWARD=Major -v <bin folder>:/app mcr.microsoft.com/dotnet/sdk:10.0 dotnet /app/FixLab.dll
Hello, World!
The environment variable changed only that run. To make it part of the build, add the property to the project file and rebuild:
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RollForward>Major</RollForward>
After dotnet build -c Release the runtimeconfig carried
"rollForward": "Major", and the original docker run command,
without the variable, printed Hello, World!. Roll-forward is a convenience, not
a promise: a newer major version can contain breaking changes, so test the app on it before
relying on it. In a Dockerfile, the cleaner answer is to run the app on a runtime image that
matches its target, such as mcr.microsoft.com/dotnet/runtime:8.0 (or
aspnet:8.0 for a web app), or to retarget the project to net10.0.
How it was reproduced
On Windows 11 with .NET SDK 10.0.401 and Docker 29.8.2: a console project from
dotnet new console -n FixLab -f net8.0, built framework-dependent with
dotnet build -c Release on the host. Its bin\Release\net8.0 folder
was mounted into the cached mcr.microsoft.com/dotnet/sdk:10.0 image, whose
runtime is 10.0.10, and started with dotnet /app/FixLab.dll. The container name
fix4-net8 is the test's own; it was removed after each run.
Frequently asked
- Can a .NET 8 app run on the .NET 10 runtime?
- Not by default. The host rolls forward only within the same major version. Setting DOTNET_ROLL_FORWARD=Major or RollForward=Major in the project lets it start on .NET 10, but test it first because major versions can contain breaking changes.
- Why does my .NET 8 app fail in the dotnet sdk:10.0 Docker image?
- The SDK image can build for older targets but carries only the .NET 10 runtime. Run the app on a matching runtime image such as mcr.microsoft.com/dotnet/runtime:8.0, or allow roll-forward.
- What does exit code 150 mean for dotnet?
- In this test the host returned 150 when the required framework was missing. The message above it lists the framework the app asked for and the versions it found, which is the part to read.
If the problem is the SDK version rather than the runtime, see A compatible .NET SDK was not found. More decoded errors are in the Fixes category.