Skip to content
Latchkey

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.

.NET
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

  1. Choose the RID for your deploy target (for example linux-x64).
  2. Publish with -r <rid>; modern SDKs restore the RID during publish.
  3. Choose self-contained or framework-dependent explicitly.
Terminal
dotnet publish -c Release -r linux-x64 --self-contained true -o out

Restore the RID first if needed

On older SDKs or with --no-restore, restore for the RID before publishing.

Terminal
dotnet restore -r linux-x64
dotnet publish -c Release -r linux-x64 --no-restore -o out

How 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.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →