signalapp/Signal-Server · warning
return Response.status(422).build();
Error message
return Response.status(422).build();
What it means
JsonMappingExceptionMapper handles Jackson JsonMappingExceptions during request deserialization. Client-abort cases (Jetty EofException or 'Early EOF' messages) map to 400 Bad Request; every other mapping failure — meaning the JSON was syntactically parsed but did not match the target type — returns HTTP 422 Unprocessable Entity.
Solutions
- Validate the request JSON against the endpoint's expected schema before sending (correct field names and types)
- Update the client to match the server's current API model after version changes
- Capture the 422 and log the request body to identify the offending field
- If a valid payload is rejected, check custom Jackson deserializers/annotations on the DTO
Example fix
// before
Request.Body("{"deviceId": "17"}"); // deviceId as string, DTO expects int
// after
Request.Body("{"deviceId": 17}"); // match DTO field types Defensive patterns
Strategy: validation
Validate before calling
// validate the payload shape before sending ObjectNode body = mapper.valueToTree(dto); mapper.readerFor(dto.getClass()).readValue(mapper.writeValueAsBytes(body)); // dry-run roundtrip
Try / catch
if (response.code() == 422) {
log.error("payload rejected, body=" + lastRequestBody);
refreshApiModelAndReserialize();
} else if (response.code() == 400) {
reconnect(); // early EOF / truncated body
} Prevention
- Serialize DTOs through the same Jackson version as the server's API model
- Dry-run deserialize payloads client-side before sending
- Keep client/server API schemas in sync after upgrades
- Detect truncated uploads (Early EOF -> 400) and retry whole-body sends
When it happens
Trigger: Sending a request body whose JSON shape doesn't fit the endpoint's DTO: wrong field types, missing required properties handled as mapping errors, or enum/object coercion failures.
Common situations: API clients sending old/changed payload schemas after a server upgrade; hand-rolled JSON missing nested objects; clients truncating bodies (that path instead yields 400 via Early EOF); content-type mismatches producing wrong binding.
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
- Could not interpret identity key bytes as an EC public key
- Could not parse key as a base64-encoded value
- Could not interpret bytes as a ZK credential public key
- return Response.status(429).build();
- return Response.status(404).build();
AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09).
Data as JSON: /api/errors/97af1c8d7ef35578.
Report an issue: GitHub.
Appendix: source
Thrown at service/src/main/java/org/whispersystems/textsecuregcm/mappers/JsonMappingExceptionMapper.java:18
package org.whispersystems.textsecuregcm.mappers;
import com.fasterxml.jackson.databind.JsonMappingException;
import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.ext.ExceptionMapper;
public class JsonMappingExceptionMapper implements ExceptionMapper<JsonMappingException> {
@Override
public Response toResponse(final JsonMappingException exception) {
if (exception.getCause() instanceof java.util.concurrent.TimeoutException) {
return Response.status(Response.Status.REQUEST_TIMEOUT).build();
}
if (exception.getCause() instanceof org.eclipse.jetty.io.EofException
|| exception.getMessage() != null && exception.getMessage().startsWith("Early EOF")) {
// Some sort of timeout or broken connection
return Response.status(Response.Status.BAD_REQUEST).build();
}
return Response.status(422).build();
}
}
View on GitHub (pinned to 100ab61c82)