Is .NET Core Runtime backwards compatible with previous releases?

Edit .NET Core 3.x SDK has been released. Unlike v2.2 and the previous releases before it, this version does not support the ability to target previous runtimes (i.e. netcoreapp2.2, netcoreapp2.1, etc)

tldr;

Yes. By installing .NET Core Runtime 2.2.3, you can run apps which target netcoreapp2.0, netcoreapp2.1, and netcoreapp2.2, without requiring additional runtimes to be installed.

Explanation

Microsoft:

...NET Core runtime updates are compatible within a major version 'band' such as 1.x and 2.x.

In other words: (Minor updates within the same major release are backwards compatible)

Microsoft:

Additionally, newer releases of the .NET Core SDK generally maintain the ability to build applications that target previous versions of the runtime in a compatible manner

In other words: (The latest SDK can target previous runtimes)

Microsoft:

In general, you only need the latest SDK and latest patch version of the runtimes required for your application.

In other words: (Generally speaking, you should only need to install the latest SDK/runtime)

Microsoft:

Over time, as you install updated versions of the .NET Core runtime and SDK, you may want to remove outdated versions of .NET Core from your machine. Removing older versions of the runtime may change the runtime chosen to run shared framework applications

In other words: (As you install additional SDKs/runtimes side-by-side over time, you should occasionally remove older versions, in favor of the latest)

Source: https://docs.microsoft.com/en-us/dotnet/core/versions/remove-runtime-sdk-versions?tabs=windows

.NET Core Versioning

According to documentation:

".NET Core 2.1" refers to the .NET Core Runtime version number. The .NET Core Runtime has a major/minor/patch approach to versioning that follows semantic versioning.

In other words, .NET Core runtime releases follow the Semantic Versioning scheme:

[Major].[Minor].[Patch]

Where:

  • Major upgrades introduce breaking changes
  • Minor upgrades are feature upgrades that are backwards-compatible with previous minor releases
  • Patch upgrades are generally bug fixes or security patches to existing features (also backwards compatible with previous minor releases)

So, the answer to the above question is based on Semantic Versioning:

  • Major upgrades are not backwards compatible with the previous major version
  • Minor and/or patch upgrades are backwards-compatible within the same version

With this understanding, when .NET Core apps are built/published/restored, they target a major release and feature set as indicated by the major/minor version numbers found in the runtime name. So, netcoreapp2.2 is backwards compatible with netcoreapp2.1, which, in turn, is backwards-compatible with netcoreapp2.0. But all are incompatible with netcoreapp1.x or netcoreapp3.x.

With one installation of .NET Core 2.1.5 runtime, and assuming a framework-dependent publish deployment, you would be able to run apps targeting:

  • netcoreapp2.0
  • netcoreapp2.1

But not:

  • netcoreapp1.0 (incompatible)
  • netcoreapp2.2 (not yet supported)

If there are multiple runtimes installed, then the exact runtime is chosen based on the latest runtime installed with the highest patch.

About the SDK

The SDK is not based on Semantic Versioning. However, each SDK targets a maximum .NET Core Runtime, and supports every version prior to it.

That means, you don't need to install more than one SDK on your build server if you want to build against multiple runtimes (even though you could). The SDK already includes all the necessary runtimes to build applications on the current version (or any prior version) out-of-the-box. For example, if you install .NET Core 2.2.105 SDK, you can build for netcoreapp1.0, netcoreapp2.0, netcoreapp2.1, or netcoreapp2.2. But you can't build for .NET Core 2.3, or 3.0.

An Example

Suppose I have a build server, which has the latest .NET Core SDK installed (SDK 2.2.105 - 2.2.3 Runtime).

Although, SDK 2.2.105 is installed, I might want to build and publish a .NET Core 2.1 app:

dotnet publish 
     /p:Configuration=Release -r win-x64 --self-contained false
     /p:IsWebConfigTransformDisabled=true --framework netcoreapp2.1
     /p:DebugSymbols=false /p:DebugType=None
  • /p:Configuration=Release - configure for Release
  • -r win-x64 - target Windows deployment (rather than portable). For a complete list refer to this https://docs.microsoft.com/en-us/dotnet/core/rid-catalog.
  • --self-contained false - Framework dependent deployment (requires runtime to be installed on host)
  • /p:IsWebConfigTransformDisabled=true - do not transform web.config to avoid errors with the default web.config generated by Visual Studio (may be needed when migrating from 2.1 to 2.2)
  • --framework netcoreapp2.1 - explicitly target a runtime framework
  • /p:DebugSymbols=false /p:DebugType=None - disable .PDB files

This build could be installed on a Production server with the latest runtime .NET Core Runtime + Hosting Bundle 2.2.3 - no other runtimes (or SDK) are necessary

Hope this helps someone else


A few usage examples demonstrate the behavior, if you target 2.0:

  1. 2.0 is specified. 2.0.5 is the highest patch version installed. 2.0.5 is used.
  2. 2.0 is specified. No 2.0.* versions are installed. 1.1.1 is the highest runtime installed. An error message is displayed.
  3. 2.0 is specified. No 2.0.* versions are installed. 2.2.2 is the highest 2.x runtime version installed. 2.2.2 is used.
  4. 2.0 is specified. No 2.x versions are installed. 3.0.0 is installed. An error message is displayed.

Please refer following link in Microsoft Docs Microsoft Link