microsoft/aspire · error

File ' ' exceeded the expected size of bytes.

Error message

File '{fileName}' exceeded the expected size of {expectedSize} bytes.

What it means

DashboardClient validates file upload size while streaming chunks to the dashboard service over gRPC. The library throws this InvalidOperationException as soon as cumulative bytes read from the file exceed the expected size recorded when the upload was initiated, preventing oversized or concurrently-modified files from being silently uploaded. It is a safety check against the file changing between size measurement and streaming.

Solutions

  1. Stop writing to the file (or take a snapshot/copy) before starting the upload, then retry the upload
  2. Re-measure the file size immediately before the upload so expectedSize matches current content
  3. Retry the upload after the file stabilizes; if the file is legitimately larger, initiate a new upload with the new expected size

Example fix

// before: upload a file while the app still appends to it
await client.UploadFileAsync(liveLogPath);

// after: snapshot the file first so size and content cannot diverge
var snapshotPath = Path.Combine(tempDir, Path.GetFileName(liveLogPath));
File.Copy(liveLogPath, snapshotPath, overwrite: true);
await client.UploadFileAsync(snapshotPath);
Defensive patterns

Strategy: validation

Validate before calling

var fileInfo = new FileInfo(path);
if (!fileInfo.Exists || fileInfo.Length == 0)
{
    throw new FileNotFoundException(path);
}
// ensure the file is not actively growing before uploading
await Task.Delay(500); // optional stability check
if (new FileInfo(path).Length != fileInfo.Length)
{
    // file is still being written; snapshot or wait before upload
}

Try / catch

try
{
    await UploadFileAsync(path);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("exceeded the expected size"))
{
    // re-snapshot and retry with a fresh expected size
}

Prevention

When it happens

Trigger: Calling the dashboard client's file upload API when the on-disk file grows (or was measured incorrectly) after its size was computed: totalBytesRead exceeds expectedSize during the ReadAsync loop.

Common situations: A log file or trace file is still being appended to by the application while it is being uploaded; the file was swapped or truncated/expanded between the size query and the stream read; uploading a live-growing artifact in a shared directory.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/1e4800909ffe26cc. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Dashboard/ServiceClient/DashboardClient.cs:1126

    public async Task<string> UploadFileAsync(Stream fileStream, string fileName, long expectedSize, int interactionId, string inputName, CancellationToken cancellationToken)
    {
        EnsureInitialized();

        using var combinedTokens = CancellationTokenSource.CreateLinkedTokenSource(_clientCancellationToken, cancellationToken);
        using var call = _client!.UploadFile(headers: _headers, cancellationToken: combinedTokens.Token);

        const int chunkSize = 64 * 1024; // 64 KB chunks
        var buffer = new byte[chunkSize];
        var isFirst = true;
        long totalBytesRead = 0;

        int bytesRead;
        while ((bytesRead = await fileStream.ReadAsync(buffer, combinedTokens.Token).ConfigureAwait(false)) > 0)
        {
            totalBytesRead += bytesRead;
            if (totalBytesRead > expectedSize)
            {
                throw new InvalidOperationException($"File '{fileName}' exceeded the expected size of {expectedSize} bytes.");
            }

            var chunk = new UploadFileChunk
            {
                Data = Google.Protobuf.ByteString.CopyFrom(buffer, 0, bytesRead)
            };

            if (isFirst)
            {
                chunk.FileName = fileName;
                chunk.InteractionId = interactionId;
                chunk.InputName = inputName;
            }

            await call.RequestStream.WriteAsync(chunk, combinedTokens.Token).ConfigureAwait(false);
            isFirst = false;
        }

View on GitHub (pinned to 25830f84bd)