bitwarden/server · error · BadRequestException
File received does not match expected constraints.
Error message
File received does not match expected constraints.
What it means
Thrown after the self-hosted upload stream completes when ValidateFileAsync reports the received file size is outside the accepted window: [fileData.Size − 1MB, min(fileData.Size + 1MB, 501MB)]. On failure the controller deletes the uploaded blob, deletes the report record, and evicts the reports cache before throwing — so the report is fully rolled back.
Source
Thrown at src/Api/Dirt/Controllers/OrganizationReportsController.cs:420
throw new NotFoundException();
}
await Request.GetFileAsync(async (stream) =>
{
await _storageService.UploadReportDataAsync(report, fileData, stream);
});
var leeway = 1024L * 1024L; // 1 MB
var minimum = Math.Max(0, fileData.Size - leeway);
var maximum = Math.Min(fileData.Size + leeway, Constants.FileSize501mb);
var (valid, length) = await _storageService.ValidateFileAsync(report, fileData, minimum, maximum);
if (!valid)
{
await _storageService.DeleteReportFilesAsync(report, fileData.Id!);
await _organizationReportRepo.DeleteAsync(report);
await _cache.RemoveByTagAsync(
OrganizationReportCacheConstants.BuildCacheTagForOrganizationReports(organizationId));
throw new BadRequestException("File received does not match expected constraints.");
}
fileData.Validated = true;
fileData.Size = length;
report.SetReportFile(fileData);
report.RevisionDate = DateTime.UtcNow;
await _organizationReportRepo.ReplaceAsync(report);
await _cache.RemoveByTagAsync(
OrganizationReportCacheConstants.BuildCacheTagForOrganizationReports(organizationId));
}
/// <summary>
/// Downloads an organization report file for a self-hosted instance.
/// Validates that the organization ID and report ID are non-empty,
/// then authorizes the caller via <see cref="AuthorizeAsync"/>.
/// Verifies the report exists and belongs to the specified organization.
/// Retrieves the file metadata and streams the file from local storage.
/// Cloud-hosted instances download files directly from Azure Blob StorageView on GitHub (pinned to e93b962371)
Solutions
- Measure the exact byte length of the bytes you actually stream and set FileSize to that same value at create-report time.
- If the source changed, create a NEW report (new FileSize) rather than re-uploading to the existing one.
- Check for proxy/WAF body-size limits between client and server that could truncate the upload.
Example fix
// before: FileSize from source file, upload from compressed stream
var req = new AddOrganizationReportRequestModel { FileSize = new FileInfo(srcPath).Length };
// after: measure the exact bytes you upload
using var ms = new MemoryStream();
CompressTo(srcPath, ms);
var req = new AddOrganizationReportRequestModel { FileSize = ms.Length }; Defensive patterns
Strategy: validation
Validate before calling
// Set FileSize to the exact byte count of the stream you will upload using var ms = new MemoryStream(); await PrepareUploadStreamAsync(source, ms); var fileSize = ms.Length; // pass fileSize as request.FileSize at create-report time
Try / catch
try { await client.PostAsync(uploadUrl, multipart); }
catch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.BadRequest && ex.Message.Contains("constraints"))
{ /* report was rolled back — recreate with correct FileSize and re-upload */ } Prevention
- Measure the actual upload byte length and use it as FileSize.
- Never re-upload a different-sized file to the same report.
- Watch for proxy/WAF body truncation between client and server.
When it happens
Trigger: The actual uploaded byte count differs from the FileSize declared at create-report time by more than 1 MiB in either direction; the upload was truncated (network drop, proxy limit) or padded/corrupted.
Common situations: Client computes FileSize from the source file but uploads a transformed/compressed version; network interruption truncates the multipart body but the connection appears to close cleanly; intermediary (reverse proxy, WAF) strips or adds bytes; client retries upload to the same report with a different-sized file.
Related errors
- Max file size is 500 MB.
- ReportFileId is required.
- Resource not found.
- Invalid content.
- ReportFileId query parameter is required
AI-assisted analysis of bitwarden/server@e93b962371 (2026-08-13).
Data as JSON: /api/errors/4a9b89055ef38e5c.
Report an issue: GitHub.