jwtk/jjwt · error · JSONException
Unable to obtain JSON String from Reader:
Error message
Unable to obtain JSON String from Reader:
What it means
OrgJsonDeserializer.newTokener wraps an IOException raised while reading the whole JSON string from a Reader into a JSONException with this message. It happens on the fallback path (no JSONTokener(Reader) constructor available, e.g. older org.json or Android) when the reader itself fails mid-read.
Source
Thrown at extensions/orgjson/src/main/java/io/jsonwebtoken/orgjson/io/OrgJsonDeserializer.java:169
int n = 0;
while (EOF != n) {
n = reader.read(buf);
if (n > 0) sb.append(buf, 0, n);
}
return sb.toString();
}
private JSONTokener newTokener(Reader reader) {
if (this.readerCtorAvailable) {
return new JSONTokener(reader);
}
// otherwise not available, likely Android or earlier org.json version, fall back to String ctor:
String s;
try {
s = toString(reader);
} catch (IOException ex) {
String msg = "Unable to obtain JSON String from Reader: " + ex.getMessage();
throw new JSONException(msg, ex);
}
return new JSONTokener(s);
}
}
}
View on GitHub (pinned to fb71496164)
Solutions
- Ensure the underlying stream is open and fully readable before parsing
- Read the token source fully into a String yourself with proper IOException handling, then parse the String
- Catch JSONException (getCause() instanceof IOException) and handle/retry the read
- Use a fresh InputStream per parse — streams cannot be reused after consumption
Example fix
// before Jwts.parser().build().parse(inputReader); // JSONException wrapping IOException // after String jwt = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8); Jwts.parser().build().parse(jwt);
Defensive patterns
Strategy: try-catch
Validate before calling
if (!reader.ready()) throw new IllegalStateException("Reader not ready before JSON parse"); Try / catch
try {
jwt = Jwts.parser().build().parse(readerSource);
} catch (JSONException e) {
if (e.getCause() instanceof IOException io) throw new UncheckedIOException("Failed reading JWT source", io);
throw e;
} Prevention
- Read the token fully into a String before parsing instead of streaming readers
- Never reuse consumed InputStreams/Readers; open a fresh source per parse
- Handle transient IO failures on network token sources with bounded retries
When it happens
Trigger: Parsing a JWT/JSON from an InputStream/Reader whose underlying stream throws IOException — closed stream, network socket reset, or unreadable source — on platforms lacking the tokener-from-reader constructor.
Common situations: Reading tokens from an HTTP body stream that timed out or was closed early; Android devices with old org.json; reusing already-consumed streams.
Understand the failure class
Background: "failed to read file", EACCES, ENOENT and "could not read <path>" errors: when a program can't read a file from disk — this error's family across 49 libraries.
Related errors
- Unexpected unsecured Claims JWT.
- Unexpected content JWS.
- Unexpected Claims JWS.
- Unexpected content JWE.
- Unexpected Claims JWE.
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/24da921e7b11a52d.
Report an issue: GitHub.