ASP.NET Core "dotnet publish" self-contained / runtime identifier failure in CI
A self-contained or runtime-specific publish needs a runtime identifier (RID) that matches the deploy target and packages that support it. In CI it fails when the RID is missing, wrong for the runner, or a self-contained option conflicts with the project.
What this error means
A dotnet publish step errors with "You must specify a target framework" plus a RID prompt, "NETSDK1047: Assets file ... doesn't have a target for ...", or a self-contained/single-file conflict.
error NETSDK1047: Assets file '/home/runner/work/app/obj/project.assets.json'
doesn't have a target for 'net8.0/linux-x64'. Ensure that restore has run and
that you have included 'net8.0' in the TargetFrameworks... and a RuntimeIdentifier.Common causes
The RID was not restored
Publishing for linux-x64 requires a restore that includes that RID; a plain restore has no target for it, so publish fails.
A self-contained option conflicts with the project
Self-contained, single-file, or trimming options may not be supported by the project as configured, breaking the publish.
How to fix it
Publish with the correct RID
- Choose the RID for your deploy target (for example
linux-x64). - Publish with
-r <rid>; modern SDKs restore the RID during publish. - Choose self-contained or framework-dependent explicitly.
dotnet publish -c Release -r linux-x64 --self-contained true -o outRestore the RID first if needed
On older SDKs or with --no-restore, restore for the RID before publishing.
dotnet restore -r linux-x64
dotnet publish -c Release -r linux-x64 --no-restore -o outHow to prevent it
- Publish with an explicit RID that matches the deploy target.
- Decide self-contained vs framework-dependent and set it consistently.
- Ensure restore covers the RID before a --no-restore publish.