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.
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.
{
"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.
- uses: actions/setup-dotnet@v4
with:
global-json-file: global.jsonHow to prevent it
- Use
latestFeature(orlatestPatch) so patch/feature drift across runners does not break builds. - Reserve
disable/patchfor environments where the exact SDK is guaranteed installed. - Keep the pinned version aligned with the SDKs your runners ship.