Skip to content
Latchkey

dotnet global.json "rollForward" Misconfiguration in CI

A global.json rollForward policy controls how far the host may move from the pinned SDK to a newer installed one. A strict policy like disable or patch rejects an SDK that would otherwise work, failing the build.

What this error means

The build fails saying the pinned SDK was not found even though a close version is installed. Loosening rollForward lets the installed SDK satisfy the pin, which confirms the policy, not the install, was the problem.

Terminal
A compatible .NET SDK was not found.
Requested SDK version: 8.0.401 (rollForward: disable)
Installed SDKs:
8.0.404 [/usr/share/dotnet/sdk]

Common causes

rollForward set to disable or patch

disable requires the exact version; patch only rolls within the same feature band. A runner with a newer patch/feature band SDK is then rejected.

Pinned version drifted ahead of the runners

A global.json pinned to a version no runner image ships, combined with a strict policy, leaves nothing to satisfy the pin.

How to fix it

Relax the rollForward policy

Allow rolling forward to a newer feature band so a close install satisfies the pin.

global.json
{
  "sdk": {
    "version": "8.0.401",
    "rollForward": "latestFeature"
  }
}

Or install exactly what global.json pins

Have CI install the precise version so even a strict policy resolves.

.github/workflows/ci.yml
- uses: actions/setup-dotnet@v4
  with:
    global-json-file: global.json

How to prevent it

  • Use latestFeature (or latestPatch) so patch/feature drift across runners does not break builds.
  • Reserve disable/patch for environments where the exact SDK is guaranteed installed.
  • Keep the pinned version aligned with the SDKs your runners ship.

Related guides

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