stride3d/stride · error · FileNotFoundException

Could not locate native executable

Error message

Could not locate native executable ${executableName}

What it means

LocateExecutable throws FileNotFoundException when a native executable cannot be found in any searched location: the NuGet native-dependencies cache, the current working directory, or the owner assembly's runtimes/<rid>/native folder. It signals that a platform-specific binary expected to ship alongside the managed assembly is missing.

Solutions

  1. Verify the native executable exists under runtimes/{current-rid}/native next to the owner assembly (e.g. runtimes/linux-x64/native/).
  2. Ensure the NuGet package includes native assets for the runtime identifier you deploy to, or add the right runtime pack / runtime.json mappings.
  3. Catch FileNotFoundException and fall back to an explicit path or a clearer error telling the user which native tool to install.
  4. Check that the executable name including extension matches exactly (case-insensitive dictionary lookup but File.Exists on the current path is platform-sensitive).

Example fix

// before
var exe = NativeLibraryHelper.LocateExecutable("StrideNativeTool", typeof(App)); // throws if missing
// after
string exe;
try { exe = NativeLibraryHelper.LocateExecutable("StrideNativeTool", typeof(App)); }
catch (FileNotFoundException)
{
    exe = Path.Combine(AppContext.BaseDirectory, "tools", "StrideNativeTool.exe");
    if (!File.Exists(exe)) throw new InvalidOperationException("StrideNativeTool is not installed with the application");
}
Defensive patterns

Strategy: try-catch

Validate before calling

static bool CanLocateExecutable(string name, Type owner) =>
    File.Exists(name) || File.Exists(Path.Combine(AppContext.BaseDirectory, "runtimes",
        $"{(Platform.Type == PlatformType.Windows ? "win" : Platform.Type == PlatformType.Linux ? "linux" : "osx")}-{RuntimeInformation.ProcessArchitecture.ToString().ToLowerInvariant().Replace("x64","x64")}", "native", name));

Try / catch

try
{
    exePath = NativeLibraryHelper.LocateExecutable(executableName, ownerType);
}
catch (FileNotFoundException ex)
{
    throw new InvalidOperationException(
    $"Native executable '{executableName}' is missing. Ensure the native assets package for {RuntimeInformation.RuntimeIdentifier} is installed.", ex);
}

Prevention

When it happens

Trigger: Calling NativeLibraryHelper.LocateExecutable(executableName, ownerType) where executableName is neither registered as a packaged native dependency, present in the current directory, nor found under the owner assembly's runtimes/{platform}-{cpu}/native path.

Common situations: NuGet package published without the native runtime assets for the current RID (e.g. built for win-x64 but run on linux-x64); executable renamed between package versions; running from a publish output that stripped native tools; wrong working directory when relying on relative-path lookup.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/f23c8357be57a872. Report an issue: GitHub.

Appendix: source

Thrown at sources/core/Stride.Core/Native/NativeLibraryHelper.cs:111

    /// </exception>
    /// <remarks>
    ///   This method is typically used to resolve platform-specific native binaries required by managed code.
    /// </remarks>
    public static string LocateExecutable(string executableName, Type ownerType)
    {
        // NuGet native libraries
        if (nativeDependenciesWithExtensions.TryGetValue(executableName, out string? knownExePath))
            return knownExePath;

        // Try in current path
        if (File.Exists(executableName))
            return executableName;

        // Try runtimes specific path
        if (TryFindLibraryPath(ownerType, executableName, out knownExePath))
            return knownExePath;

        throw new FileNotFoundException($"Could not locate native executable {executableName}");
    }

    /// <summary>
    ///   Locates the full path to a native library, appending the current platform's library
    ///   extension (<c>.dll</c>, <c>.so</c>, <c>.dylib</c>) to <paramref name="libraryName"/> before
    ///   searching. On Linux/macOS, SONAME-versioned variants (for example, <c>libfoo.so.6</c> or
    ///   <c>libfoo.6.dylib</c>) are matched and the highest version is returned; the <c>lib</c> prefix
    ///   is also tried when omitted, matching the conventions <see cref="PreloadLibrary"/> uses.
    /// </summary>
    /// <param name="libraryName">The library name without extension (for example, <c>"libassimp"</c> or <c>"assimp"</c>).</param>
    /// <param name="ownerType">
    ///   The type whose assembly is used to determine runtime-specific search paths for the library.
    /// </param>
    /// <returns>The full path to the located native library.</returns>
    /// <exception cref="FileNotFoundException">
    ///   Thrown if the library cannot be found in any of the searched locations.
    /// </exception>
    public static string LocateLibrary(string libraryName, Type ownerType)

View on GitHub (pinned to 96fad776d2)