dotnet/orleans · critical · FileNotFoundException

Embedded resource not found: {fullResourceName}

Error message

Embedded resource not found: {fullResourceName}

What it means

FileNotFoundException (message 'Embedded resource not found') from EmbeddedAssetProvider.CreateResourceEntry when Assembly.GetManifestResourceStream(fullResourceName) returns null. The Orleans Dashboard serves static assets (JS/CSS) from embedded manifest resources; if the resource name does not exactly match an embedded resource, the stream is null and the provider throws. This is built at endpoint-configuration time, so it typically surfaces at app startup.

Source

Thrown at src/Dashboard/Orleans.Dashboard/EmbeddedAssetProvider.cs:99

            return false;
        }

        for (int i = 0; i < acceptEncoding.Count; i++)
        {
            var encoding = acceptEncoding[i];
            if (encoding.Quality is not 0 &&
                string.Equals(encoding.Value.Value, GZipEncodingValue, StringComparison.OrdinalIgnoreCase))
            {
                return true;
            }
        }

        return false;
    }

    private static ResourceEntry CreateResourceEntry(string fullResourceName)
    {
        using var resourceStream = Assembly.GetManifestResourceStream(fullResourceName) ?? throw new FileNotFoundException($"Embedded resource not found: {fullResourceName}");
        using var decompressedContent = new MemoryStream();
        resourceStream.CopyTo(decompressedContent);
        var decompressedArray = decompressedContent.ToArray();

        // Compress the content
        using var compressedContent = new MemoryStream();
        using (var gzip = new GZipStream(compressedContent, CompressionMode.Compress, leaveOpen: true))
        {
            gzip.Write(decompressedArray);
        }

        // Only use compression if it actually reduces size
        byte[]? compressedArray = compressedContent.Length < decompressedArray.Length
            ? compressedContent.ToArray()
            : null;

        var hash = SHA256.HashData(compressedArray ?? decompressedArray);
        var eTag = $"\"{Convert.ToBase64String(hash)}\"";

View on GitHub (pinned to fca799fa70)

Solutions

  1. Ensure the Orleans.Dashboard project/package is intact and its assets are marked as EmbeddedResource in the consuming build.
  2. For trimmed/single-file publishes, exclude the dashboard assembly from trimming so embedded resources are preserved.
  3. Verify the resource name casing and full qualification matches what the assembly embeds (use ildasm/reflection to list GetManifestResourceNames()).

Example fix

// before (custom asset not embedded)
services.AddDashboard(o => o.AssetOverride = "MyApp.assets.index.min.js");

// after
// .csproj: <ItemGroup><EmbeddedResource Include="assets\index.min.js" /></ItemGroup>
// and reference via the correct default name, or confirm with:
foreach (var n in typeof(DashboardMiddleware).Assembly.GetManifestResourceNames()) Console.WriteLine(n);
Defensive patterns

Strategy: validation

Validate before calling

var names = typeof(DashboardMiddleware).Assembly.GetManifestResourceNames();
if (!names.Contains(fullResourceName))
    throw new FileNotFoundException($"Missing embedded resource {fullResourceName}. Available: {string.Join(",", names)}");

Type guard

static bool ResourceExists(Assembly a, string name) =>
    a.GetManifestResourceNames().Contains(name);

Try / catch

try { app.MapOrleansDashboard(); }
catch (FileNotFoundException ex) when (ex.Message.Contains("Embedded resource not found"))
{ logger.LogCritical(ex, "Dashboard assets missing; check embedding/trimming"); throw; }

Prevention

When it happens

Trigger: MapOrleansDashboard resolving a route whose asset name does not match any embedded manifest resource. The default asset set is embedded at build time; a renamed resource, a stripped/incomplete publish, or a mismatched default resource list will trigger it.

Common situations: Publishing a trimmed/single-file build that removed embedded resources, a Dashboard package version mismatch (asset list changed but caller references old name), or a custom asset override that did not set BuildAction=EmbeddedResource. Also when the dashboard assembly is referenced via a package but the .csproj did not embed the wwwroot assets.

Related errors


AI-assisted analysis of dotnet/orleans@fca799fa70 (2026-08-13). Data as JSON: /api/errors/9a4ca2d7ad35cec2. Report an issue: GitHub.