{"record":{"id":"bc324be7ff1df81f","repo":"bitwarden/server","slug":"multipart-boundary-length-limit-lengthlimit-exce","errorCode":null,"errorMessage":"Multipart boundary length limit {lengthLimit} exceeded.","messagePattern":"Multipart boundary length limit (.+?) exceeded\\.","errorType":"exception","errorClass":"InvalidDataException","httpStatus":400,"severity":"error","filePath":"src/Api/Utilities/MultipartFormDataHelper.cs","lineNumber":135,"sourceCode":"                    await callback(dataSection.Body);\n                }\n            }\n            dataSection = null;\n        }\n    }\n\n\n    private static string GetBoundary(MediaTypeHeaderValue contentType, int lengthLimit)\n    {\n        var boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary);\n        if (StringSegment.IsNullOrEmpty(boundary))\n        {\n            throw new InvalidDataException(\"Missing content-type boundary.\");\n        }\n\n        if (boundary.Length > lengthLimit)\n        {\n            throw new InvalidDataException($\"Multipart boundary length limit {lengthLimit} exceeded.\");\n        }\n\n        return boundary.ToString();\n    }\n\n    private static bool HasFileContentDisposition(ContentDispositionHeaderValue content)\n    {\n        // Content-Disposition: form-data; name=\"data\"; filename=\"Misc 002.jpg\"\n        return content != null && content.DispositionType.Equals(\"form-data\") &&\n            (!StringSegment.IsNullOrEmpty(content.FileName) || !StringSegment.IsNullOrEmpty(content.FileNameStar));\n    }\n\n    private static bool HasDispositionName(ContentDispositionHeaderValue content, string name)\n    {\n        // Content-Disposition: form-data; name=\"key\";\n        return content != null && content.DispositionType.Equals(\"form-data\") && content.Name == name;\n    }\n}","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/bitwarden/server/blob/e93b962371d80964556f5590c6615f5160a437a1/src/Api/Utilities/MultipartFormDataHelper.cs#L117-L153","documentation":"In the same GetBoundary path, the boundary string must not exceed FormOptions.MultipartBoundaryLengthLimit (default 128 characters). An over-long boundary is rejected to prevent abuse and parser strain, throwing InvalidDataException (HTTP 400).","triggerScenarios":"A client sends a multipart boundary token longer than the configured limit (default 128 chars).","commonSituations":"A custom boundary generator producing very long random strings; a gateway rewriting the boundary; the default limit having been lowered in server config.","solutions":["Use a short boundary (<= 70 characters is typical and safe).","Let the HTTP library generate the boundary instead of supplying one.","If a longer boundary is genuinely required, raise FormOptions.MultipartBoundaryLengthLimit in server configuration."],"exampleFix":"// before\nContent-Type: multipart/form-data; boundary=----WebKitFormBoundaryAAAA...200chars\n// after\nContent-Type: multipart/form-data; boundary=----boundary123","handlingStrategy":"validation","validationCode":"const BOUNDARY_LIMIT = 128; // server default\nfunction makeBoundary() {\n  const b = '----bw' + Math.random().toString(36).slice(2, 10);\n  if (b.length > BOUNDARY_LIMIT) throw new Error('Generated boundary too long');\n  return b;\n}","typeGuard":"function isBoundaryShortEnough(boundary: string, limit = 128): boolean {\n  return typeof boundary === 'string' && boundary.length <= limit;\n}","tryCatchPattern":null,"preventionTips":["Keep generated boundaries short (<= 70 chars).","Let the HTTP library generate the boundary when possible.","If raising the server limit, coordinate the change across services."],"tags":["multipart","upload","content-type","http","config","bad-request"],"backgroundTag":null,"analyzedSha":"e93b962371d80964556f5590c6615f5160a437a1","analyzedAt":"2026-08-13T14:22:19.382Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}