{"record":{"id":"983e0d48e331bebc","repo":"bitwarden/server","slug":"max-file-size-is-500-mb","errorCode":null,"errorMessage":"Max file size is 500 MB.","messagePattern":"Max file size is 500 MB\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"src/Api/Dirt/Controllers/OrganizationReportsController.cs","lineNumber":115,"sourceCode":"        EnsureValidIds(organizationId);\n\n        await AuthorizeAsync(organizationId);\n\n        // File storage only exists under the new architecture, so gate the file path on the (stable)\n        // AccessIntelligenceNewArchitecture flag. Within that, select the path from the request shape\n        // rather than the file-storage flag (AccessIntelligenceVersion2): the client chooses its shape\n        // from that flag via a config cache that can lag the server by up to an hour (pronounced in\n        // self-hosted), so branching on it here would 500 whenever the two disagree. Honoring the shape\n        // lets file-storage flag staleness degrade gracefully.\n        var isNewArchitecture = _featureService.IsEnabled(FeatureFlagKeys.AccessIntelligenceNewArchitecture);\n        if (isNewArchitecture && request.FileSize.HasValue)\n        {\n            // This caps the claimed file-size value only. The file itself is uploaded separately to\n            // blob storage via UploadReportFileAsync, so no large body flows through this endpoint and\n            // no request-body size limit belongs here (that limit lives on the upload endpoint).\n            if (request.FileSize.Value > Constants.FileSize501mb)\n            {\n                throw new BadRequestException(\"Max file size is 500 MB.\");\n            }\n\n            var report = await _createReportCommand.CreateAsync(request.ToData(organizationId));\n            var fileData = report.GetReportFile()!;\n            var reportFileUploadUrl = await _storageService.GetReportFileUploadUrlAsync(report, fileData);\n\n            return Ok(new OrganizationReportFileResponseModel\n            {\n                ReportFileUploadUrl = reportFileUploadUrl,\n                ReportResponse = new OrganizationReportResponseModel(report),\n                FileUploadType = _storageService.FileUploadType\n            });\n        }\n\n        var v1Report = await _addOrganizationReportCommand.AddOrganizationReportAsync(request.ToData(organizationId));\n        var response = v1Report == null ? null : new OrganizationReportResponseModel(v1Report);\n        return Ok(response);\n    }","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/Dirt/Controllers/OrganizationReportsController.cs#L97-L133","documentation":"Thrown by POST /reports/organizations/{organizationId} when the AccessIntelligenceNewArchitecture feature flag is enabled AND the request body's FileSize exceeds Constants.FileSize501mb (the 500 MB cap). FileSize is a client-claimed value used to provision blob upload; the actual file is uploaded separately to the upload endpoint which carries its own RequestSizeLimit. This gate prevents creating a report for a file that can never be accepted.","triggerScenarios":"Client sends AddOrganizationReportRequestModel with FileSize > ~525,336,576 bytes (500 MiB + 1 MiB constant) while new architecture is on. Note FileSize must have a value (HasValue); if null the inline-data path is taken instead.","commonSituations":"Client computes FileSize incorrectly (e.g. reports bytes vs MB, or includes padding); very large risk-intelligence export exceeds the cap; feature flag flipped on for an org whose client wasn't updated to chunk uploads.","solutions":["Reduce the report payload to under 500 MB before creating the report.","If the source data is larger, split it into multiple reports or compress before reporting FileSize.","Verify the client is setting FileSize in bytes and not accidentally doubling or adding units."],"exampleFix":"// before\nvar req = new AddOrganizationReportRequestModel { FileSize = rawBytes /* could exceed cap */ };\n// after\nconst long Max = 500L * 1024 * 1024;\nif (rawBytes > Max) throw new InvalidOperationException(\"Report too large; split or compress.\");\nvar req = new AddOrganizationReportRequestModel { FileSize = rawBytes };","handlingStrategy":"validation","validationCode":"const long MaxFileSize = 500L * 1024 * 1024; // mirror server cap\nif (request.FileSize.HasValue && request.FileSize.Value > MaxFileSize)\n    throw new InvalidOperationException(\"Report file exceeds the 500 MB server cap; split or compress.\");","typeGuard":null,"tryCatchPattern":"try { var resp = await client.PostAsync(createUrl, json); }\ncatch (HttpRequestException ex) when (ex.StatusCode == HttpStatusCode.BadRequest && ex.Message.Contains(\"Max file size\"))\n{ /* reduce payload and retry */ }","preventionTips":["Compute FileSize from the exact bytes you will upload.","Split or compress reports that approach 500 MB.","Surface the cap to users before they attempt large uploads."],"tags":["validation","file-upload","feature-flag","size-limit","csharp","aspnetcore"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}