jwtk/jjwt · error · java.io.IOException
IO Exception: ${t.getMessage()}
Error message
IO Exception: ${t.getMessage()} What it means
FilteredInputStream wraps any non-IOException Throwable raised by its delegate stream operations (read, skip, available, close, reset) into an IOException with the message 'IO Exception: <msg>'. If the original is already an IOException it is rethrown unchanged.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/io/FilteredInputStream.java:137
super.close();
} catch (Throwable t) {
onThrowable(t);
}
}
/**
* Handle any Throwable thrown; by default, throws the given exception.
* <p>
* This method provides a point to implement custom exception
* handling. The default behavior is to re-throw the exception.
* </p>
*
* @param t The IOException thrown
* @throws IOException if an I/O error occurs.
*/
protected void onThrowable(final Throwable t) throws IOException {
if (t instanceof IOException) throw (IOException) t;
throw new IOException("IO Exception: " + t.getMessage(), t);
}
/**
* Invokes the delegate's {@code mark(int)} method.
*
* @param readlimit read ahead limit
*/
@Override
public synchronized void mark(final int readlimit) {
in.mark(readlimit);
}
/**
* Invokes the delegate's {@code markSupported()} method.
*
* @return true if mark is supported, otherwise false
*/
@OverrideView on GitHub (pinned to fb71496164)
Solutions
- Inspect the exception cause: if it is already an IOException, handle that error directly.
- Call markSupported() before calling reset(); guard against unsupported reset.
- Ensure the underlying stream (file, socket) is open and available for the whole read.
- Wrap custom delegate stream code so unchecked exceptions don't leak into IO operations.
Example fix
// before
in.reset(); // throws IOException if mark not supported
// after
if (in.markSupported()) { in.reset(); } else { throw new IllegalStateException("reset not supported"); } Defensive patterns
Strategy: try-catch
Validate before calling
// Java
if (in == null) throw new IllegalArgumentException("InputStream cannot be null");
if (wantReset && !in.markSupported()) throw new IllegalStateException("reset unsupported"); Type guard
static boolean supportsReset(InputStream in) {
return in != null && in.markSupported();
} Try / catch
try {
int n = filteredIn.read(buf);
} catch (IOException e) {
Throwable cause = e.getCause();
if (cause instanceof RuntimeException) throw (RuntimeException) cause;
throw e;
} Prevention
- Check markSupported() before reset().
- Keep delegate streams open for the entire lifecycle of the filtered stream.
- Wrap custom InputStream implementations to prevent unchecked exceptions escaping read().
- Always close streams in finally/try-with-resources.
When it happens
Trigger: Any read/skip/available/close/reset call on a FilteredInputStream whose delegate throws (e.g. a RuntimeException from a custom stream, or a non-IO Throwable during stream processing).
Common situations: Custom delegate streams throwing unchecked exceptions; streams over sockets that break mid-read; reset() called when the delegate does not support marking (markSupported() false).
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
- Unable to obtain JSON String from Reader:
- Unable to Base64Url-decode InputStream: ${t.getMessage()}
- Unable to ${codecName}-encode ${name}: ${t.getMessage()}
- IO Exception ${t.getMessage()}
- Unable to read compact JWT: ${e.getMessage()}
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/3844b7f93b552404.
Report an issue: GitHub.