{"record":{"id":"bc3725f461bda88f","repo":"dotnet/aspnetcore","slug":"unable-to-read-the-antiforgery-request-token-from","errorCode":null,"errorMessage":"Unable to read the antiforgery request token from the posted form.","messagePattern":"Unable to read the antiforgery request token from the posted form\\.","errorType":"exception","errorClass":"AntiforgeryValidationException","httpStatus":null,"severity":"error","filePath":"src/Antiforgery/src/Internal/DefaultAntiforgeryTokenStore.cs","lineNumber":64,"sourceCode":"        {\n            requestToken = httpContext.Request.Headers[_options.HeaderName];\n        }\n\n        // Fall back to reading form instead\n        if (requestToken.Count == 0 && httpContext.Request.HasFormContentType && !_options.SuppressReadingTokenFromFormBody)\n        {\n            // Check the content-type before accessing the form collection to make sure\n            // we report errors gracefully.\n            IFormCollection form;\n            try\n            {\n                form = await httpContext.Request.ReadFormAsync();\n            }\n            catch (InvalidDataException ex)\n            {\n                // ReadFormAsync can throw InvalidDataException if the form content is malformed.\n                // Wrap it in an AntiforgeryValidationException and allow the caller to handle it as just another antiforgery failure.\n                throw new AntiforgeryValidationException(Resources.AntiforgeryToken_UnableToReadRequest, ex);\n            }\n            catch (IOException ex)\n            {\n                // Reading the request body (which happens as part of ReadFromAsync) may throw an exception if a client disconnects.\n                // Wrap it in an AntiforgeryValidationException and allow the caller to handle it as just another antiforgery failure.\n                throw new AntiforgeryValidationException(Resources.AntiforgeryToken_UnableToReadRequest, ex);\n            }\n\n            requestToken = form[_options.FormFieldName];\n        }\n\n        return new AntiforgeryTokenSet(requestToken, cookieToken, _options.FormFieldName, _options.HeaderName);\n    }\n\n    public void SaveCookieToken(HttpContext httpContext, string token)\n    {\n        Debug.Assert(httpContext != null);\n        Debug.Assert(token != null);","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/294cab2f9b2e03af6b953820c7ab497c3c8b7ad9/src/Antiforgery/src/Internal/DefaultAntiforgeryTokenStore.cs#L46-L82","documentation":"Thrown by DefaultAntiforgeryTokenStore.GetRequestTokensAsync (line 64) when ReadFormAsync throws InvalidDataException, indicating the posted form body is malformed (e.g., invalid multipart boundary, malformed encoding). The store wraps it in AntiforgeryValidationException with the original exception as inner, so callers treat it as just another antiforgery failure. This fires only when the request has a form content type, no header token was found, and SuppressReadingTokenFromFormBody is false.","triggerScenarios":"httpContext.Request.HasFormContentType is true, requestToken from the header is empty, ReadFormAsync() at line 58 throws InvalidDataException. This is a client-side protocol error — the multipart/form-data or urlencoded body violates ASP.NET Core's form parser limits.","commonSituations":"Multipart form body exceeds MultipartBodyLengthLimit; malformed multipart boundary; URL-encoded body with invalid characters exceeding the form value length limit; a proxy corrupting the request body; a client sending a truncated upload.","solutions":["Increase form size limits if the upload is legitimately large: builder.Services.Configure<FormOptions>(o => { o.MultipartBodyLengthLimit = long.MaxValue; }).","Inspect the InnerException (InvalidDataException) for the specific form-parse error and message number.","Ensure the client sends a well-formed Content-Type header with a correct boundary for multipart uploads.","If the token should be in the header instead, set AntiforgeryOptions.HeaderName so the form body isn't read at all."],"exampleFix":"// before — default 128MB multipart limit causing InvalidDataException on large uploads\n// after — raise the limit\nbuilder.Services.Configure<FormOptions>(options =>\n{\n    options.MultipartBodyLengthLimit = 1_073_741_824; // 1 GB\n});","handlingStrategy":"try-catch","validationCode":"// Check content length against form limits before validation\nif (httpContext.Request.ContentLength\n    > builder.Configuration.GetValue<long>(\"FormOptions:MultipartBodyLengthLimit\"))\n{\n    return BadRequest(\"Upload too large.\");\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    await _antiforgery.ValidateRequestAsync(httpContext);\n}\ncatch (AntiforgeryValidationException ex) when (ex.InnerException is InvalidDataException)\n{\n    _logger.LogWarning(ex, \"Malformed form body during antiforgery validation\");\n    return BadRequest(\"The submitted form could not be processed.\");\n}","preventionTips":["Increase MultipartBodyLengthLimit if large uploads are expected.","Set AntiforgeryOptions.HeaderName for AJAX uploads so the form body isn't parsed.","Validate Content-Type and Content-Length early in the request pipeline."],"tags":["antiforgery","security","http-request","form-parsing","upload"],"analyzedSha":"294cab2f9b2e03af6b953820c7ab497c3c8b7ad9","analyzedAt":"2026-08-06T20:08:02.189Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}