{"record":{"id":"24da921e7b11a52d","repo":"jwtk/jjwt","slug":"unable-to-obtain-json-string-from-reader","errorCode":null,"errorMessage":"Unable to obtain JSON String from Reader: ","messagePattern":"Unable to obtain JSON String from Reader: ","errorType":"exception","errorClass":"JSONException","httpStatus":null,"severity":"error","filePath":"extensions/orgjson/src/main/java/io/jsonwebtoken/orgjson/io/OrgJsonDeserializer.java","lineNumber":169,"sourceCode":"            int n = 0;\n            while (EOF != n) {\n                n = reader.read(buf);\n                if (n > 0) sb.append(buf, 0, n);\n            }\n            return sb.toString();\n        }\n\n        private JSONTokener newTokener(Reader reader) {\n            if (this.readerCtorAvailable) {\n                return new JSONTokener(reader);\n            }\n            // otherwise not available, likely Android or earlier org.json version, fall back to String ctor:\n            String s;\n            try {\n                s = toString(reader);\n            } catch (IOException ex) {\n                String msg = \"Unable to obtain JSON String from Reader: \" + ex.getMessage();\n                throw new JSONException(msg, ex);\n            }\n            return new JSONTokener(s);\n        }\n    }\n}\n","sourceCodeStart":151,"sourceCodeEnd":175,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/extensions/orgjson/src/main/java/io/jsonwebtoken/orgjson/io/OrgJsonDeserializer.java#L151-L175","documentation":"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.","triggerScenarios":"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.","commonSituations":"Reading tokens from an HTTP body stream that timed out or was closed early; Android devices with old org.json; reusing already-consumed streams.","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"],"exampleFix":"// before\nJwts.parser().build().parse(inputReader); // JSONException wrapping IOException\n// after\nString jwt = new String(inputStream.readAllBytes(), StandardCharsets.UTF_8);\nJwts.parser().build().parse(jwt);","handlingStrategy":"try-catch","validationCode":"if (!reader.ready()) throw new IllegalStateException(\"Reader not ready before JSON parse\");","typeGuard":null,"tryCatchPattern":"try {\n    jwt = Jwts.parser().build().parse(readerSource);\n} catch (JSONException e) {\n    if (e.getCause() instanceof IOException io) throw new UncheckedIOException(\"Failed reading JWT source\", io);\n    throw e;\n}","preventionTips":["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"],"tags":["java","jjwt","io","orgjson","stream"],"backgroundTag":"file-read-failed","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}