Unity-Technologies/UnityCsReference · critical · FileNotFoundException

No SDK with a valid .version file found under {sdkRoot}

Error message

No SDK with a valid .version file found under {sdkRoot}

What it means

Thrown by GetDotnetRuntimeVersion (UnityEditorMSBuildPropsTargetsGeneration.cs:303, FileNotFoundException) when the bundled DotNetSdk/sdk directory exists and contains subfolders, but none of them has a '.version' file whose second line parses as a .NET SDK version (after stripping a '-preview' style suffix). bestVersion stays null, so no SDK version can be selected for global.json.

Source

Thrown at Editor/Mono/Scripting/ScriptCompilation/MsBuild/UnityEditorMSBuildPropsTargetsGeneration.cs:303

            var version = lines[1].Trim();
            if (version.Length == 0)
                continue;
            // Strip any "-preview.x" suffix for comparison, but return the full version string.
            var numeric = version;
            var dash = numeric.IndexOf('-');
            if (dash >= 0)
                numeric = numeric.Substring(0, dash);
            if (!Version.TryParse(numeric, out var parsed))
                continue;
            if (bestParsed == null || parsed > bestParsed)
            {
                bestParsed = parsed;
                bestVersion = version;
            }
        }

        if (bestVersion == null)
            throw new FileNotFoundException($"No SDK with a valid .version file found under {sdkRoot}");

        return s_cachedDotnetRuntimeVersion = bestVersion;
    }

    public static void UpdateInstallPathFile()
    {
        Directory.CreateDirectory(Path.Combine("Library", "MSBuild"));

        //This is used by the host to find certain important files thats part of the unity install
        File.WriteAllText(Path.Combine("Library", "MSBuild", "unitylocation.txt"), EditorApplication.applicationContentsPath);
    }

    private static void UpdateReferencesProps(BuildTarget buildTarget)
    {
        var editorBuildReferences = GetModulesAssemblyPaths(true, buildTarget);
        var playerBuildReferences = GetModulesAssemblyPaths(false, buildTarget);
        PropsGenerator.Instance.UpdateReferencesProps(editorBuildReferences, playerBuildReferences);
    }

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Reinstall/repair the Unity Editor so each DotNetSdk/sdk/<ver>/.version file is present with a valid version on its second line.
  2. If you maintain a custom SDK layout, ensure each SDK folder ships a '.version' file with the version string (e.g. '8.0.318') on the second line and that it parses as MAJOR.MINOR.PATCH.
Defensive patterns

Strategy: validation

Validate before calling

var sdkRoot = Path.Combine(EditorApplication.applicationScriptingPath, "DotNetSdk", "sdk");
var valid = Directory.EnumerateDirectories(sdkRoot)
    .Select(d => Path.Combine(d, ".version"))
    .Where(File.Exists)
    .Select(f => File.ReadLines(f).Skip(1).FirstOrDefault())
    .Select(line => line?.Split('-')[0])
    .Where(t => Version.TryParse(t, out _))
    .OrderByDescending(t => Version.Parse(t))
    .FirstOrDefault();
if (valid == null)
    throw new FileNotFoundException(
        $"No SDK with a valid .version file under {sdkRoot}; repair the editor install.");

Prevention

When it happens

Trigger: The SDK folders exist but each '.version' file is missing, empty, malformed, or its version token fails Version.TryParse. Only the highest parseable version is chosen; if zero parse, this fires.

Common situations: Corrupted/incomplete bundled SDK install where version metadata files were deleted or truncated. A repackaged SDK whose '.version' format differs from the expected two-line layout.

Related errors


AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13). Data as JSON: /api/errors/c42a473d92fb9e6b. Report an issue: GitHub.