HttpMessageNotReadableException: JSON parse error
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected character ('"' (code 34)): was expecting comma to separate Object entries
Where JSON.parse stops
"id": 7
"status": "shipped"
}What it means
Spring adds JSON parse error: in front of the message Jackson threw, so the useful part is everything after the colon. Find that part in the list below and fix what it points at, either the JSON or your Java class.
Last verified on Jackson 2.21 and 3.1; Spring 6.2 and 7.0.
The validator opens with the error marked. Examples travel in the URL fragment, which browsers never send to a server.
Express Lint lays broken JSON out by bracket depth and marks the line where it stops. It changes only spaces and line breaks outside strings. Strings in either quote stay as written. If the quotes do not pair up, it leaves your text as it is. Ctrl+Z undoes it. See how it works.
- Usually
- Unrecognized token: a word where a value should beUnexpected character: a character in the wrong placeCannot deserialize: valid JSON, wrong Java typeType definition error: Jackson cannot build your classNo content to map: the body is empty
- Fix
- Read the text after
JSON parse error:.
The fix
Read the text after JSON parse error:. That is Jackson's message, and it tells you what is wrong. In the example here a comma is missing after 7, so add it. If the message is about a type (Cannot deserialize, Cannot construct), the JSON is fine and the fix is in your Java class.
{
"id": 7
"status": "shipped"
}Line 2: add ,.
{
"id": 7,
"status": "shipped"
}How the message appears
First the Spring line, which is what shows up in your log. Spring 6.2 and 7.0 print the same thing. Then what Jackson 2 and Jackson 3 print for the same body, each followed by where it stopped. The last four are other errors you will see after the same prefix. Note the Type definition error one: it is a different exception, HttpMessageConversionException.
- org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected character ('"' (code 34)): was expecting comma to separate Object entries
- com.fasterxml.jackson.core.JsonParseException: Unexpected character ('"' (code 34)): was expecting comma to separate Object entries
- at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 3, column: 3]
- tools.jackson.core.exc.StreamReadException: Unexpected character ('"' (code 34)): was expecting comma to separate Object entries
- at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); byte offset: #UNKNOWN]
- org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unrecognized token 'ok': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
- org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `com.example.Order` from Array value (token `JsonToken.START_ARRAY`)
- org.springframework.http.converter.HttpMessageConversionException: Type definition error: [simple type, class com.example.Order]
- org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: No content to map due to end-of-input
What causes it
Unrecognized token: a word where a value should be
Jackson found letters where a value should be, like
okwithout quotes. JSON only allowstrue,falseandnullwithout quotes. See Unrecognized token.Unexpected character: a character in the wrong place
This page's example is one. The comma after
7is missing, so Jackson hits the"of the next key and says it expected a comma. Trailing commas, single quotes and HTML pages give the same message with a different character code. See Unexpected character.Cannot deserialize: valid JSON, wrong Java type
The JSON parsed fine. It just does not fit your class.
from Array valuemeans a list came in and your class expects one object. See Cannot deserialize from Array value.from Stringmeans Jackson could not turn some text into a date or a number. See Cannot deserialize from String.Type definition error: Jackson cannot build your class
This one looks different:
HttpMessageConversionException: Type definition error: [simple type, class com.example.Order]. It names the class and not the reason. Usually Jackson has no constructor it can use, or the type is abstract. With a single-argument constructor you getJSON parse error: Cannot construct instance ofinstead. Both are on Cannot construct instance.No content to map: the body is empty
Jackson got nothing to read. See No content to map.
Worth knowing
NoteSpring's message does not say where in the body the problem is. Jackson 2's own message ends with an at [Source: ...] line that gives the line and column. Spring leaves it out. For a syntax error (Unrecognized token, Unexpected character), paste the body into the validator to find the spot.
NoteTwo errors may never show up in Spring. With jackson-datatype-jsr310 on the classpath, Spring read a LocalDateTime with no error. See Java 8 date/time type not supported. Spring 6.2 and 7.0 also skip keys your class does not have. See Unrecognized field. A plain Jackson 2 ObjectMapper throws both, so they can fail in a test that creates its own mapper.