symfony/http-kernel · error · BadRequestHttpException
Request payload contains invalid "form" data.
Error message
Request payload contains invalid "form" data.
What it means
Symfony's #[MapRequestPayload] argument resolver throws this BadRequestHttpException when the request body format is 'form' (form-encoded) but the payload could not be normalized into data suitable for denormalization into the controller argument type. Form data cannot be used to populate the given typed object, so the request is rejected as a 400. It signals the submitted form body does not match what the mapped type expects.
Solutions
- Send the payload as JSON (Content-Type: application/json) if the controller argument is a DTO, or change the endpoint to accept individual form fields instead of #[MapRequestPayload].
- Verify the request actually contains form fields (check request->request->all()) and that the Content-Type header matches the body.
- If form submission is intended, bind fields manually via $request->request->all() and a DTO constructor, or add a form Type instead of payload mapping.
- Clear any proxy/middleware that strips or rewrites the Content-Type or body.
Example fix
// before (client sends form-encoded body to a DTO endpoint)
curl -X POST /api/user -d 'name=John&email=j@x.com'
// after (send JSON matching the mapped type)
curl -X POST /api/user -H 'Content-Type: application/json' -d '{"name":"John","email":"j@x.com"}' Defensive patterns
Strategy: validation
Validate before calling
const ct = request.headers.get('Content-Type') ?? '';
if (!ct.includes('application/json')) {
throw new Error('Send application/json for DTO endpoints');
}
JSON.parse(rawBody); // throws early if body is not valid JSON Prevention
- Match Content-Type to the controller argument mapping (JSON for #[MapRequestPayload] DTOs).
- Send form data only to controllers that read request->request directly or use Form types.
- Document each endpoint's accepted media types and enforce them client-side.
When it happens
Trigger: Using #[MapRequestPayload] on a controller argument whose request Content-Type is application/x-www-form-urlencoded (or multipart form data) where $data is not a string/array that can be denormalized - e.g. the request body failed to parse or the format was determined as 'form' while the data was null/scalar-invalid.
Common situations: POSTing an HTML form to an API endpoint typed for a JSON-style DTO; a client sending multipart/form-data without files while the endpoint expects a structured payload; mismatched Content-Type headers versus the typed controller signature.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- Request payload contains invalid
- Request payload contains invalid
- Unsupported format: " ".
- The uid for the " " parameter is invalid.
- Mapping variadic argument "$
AI-assisted analysis of symfony/http-kernel@aa3a39d728 (2026-09-13).
Data as JSON: /api/errors/dc477a2bd293e08f.
Report an issue: GitHub.
Appendix: source
Thrown at Controller/ArgumentResolver/RequestPayloadValueResolver.php:280
if (!$this->serializer instanceof DecoderInterface || !$this->serializer->supportsDecoding($format)) {
$format = Request::getStructuredSuffixFormat($request->headers->get('CONTENT_TYPE')) ?? $format;
}
$type = match (true) {
$argument->isVariadic() => ($attribute->type ?? $argument->getType()).'[]',
'array' === $argument->getType() && null !== $attribute->type => $attribute->type.'[]',
default => $argument->getType(),
};
if (\is_array($data)) {
$data = $this->mergeParamsAndFiles($data, $request->files->all());
return $this->serializer->denormalize($data, $type, self::hasNonStringScalar($data) ? $format : 'csv', $attribute->serializationContext + self::CONTEXT_DENORMALIZE + ('form' === $format ? ['filter_bool' => true] : []));
}
if ('form' === $format) {
throw new BadRequestHttpException('Request payload contains invalid "form" data.');
}
try {
return $this->serializer->deserialize($data, $type, $format, self::CONTEXT_DESERIALIZE + $attribute->serializationContext);
} catch (UnsupportedFormatException $e) {
throw new UnsupportedMediaTypeHttpException(\sprintf('Unsupported format: "%s".', $format), $e);
} catch (NotEncodableValueException $e) {
throw new BadRequestHttpException(\sprintf('Request payload contains invalid "%s" data.', $format), $e);
} catch (UnexpectedPropertyException $e) {
throw new BadRequestHttpException(\sprintf('Request payload contains invalid "%s" property.', $e->property), $e);
}
}
private function mapUploadedFile(Request $request, ArgumentMetadata $argument, MapUploadedFile $attribute): UploadedFile|array|null
{
if ($files = $request->files->get($attribute->name ?? $argument->getName())) {
return !\is_array($files) && $argument->isVariadic() ? [$files] : $files;
}View on GitHub (pinned to aa3a39d728)