quarkusio/quarkus · warning · NotEnoughDataDecoderException
Access out of bounds
Error message
Access out of bounds
What it means
skipControlCharacters advances through the undecoded chunk discarding ISO control chars and whitespace before reading the next delimiter/disposition line. If it runs past the end of available data without finding a non-control character, NotEnoughDataDecoderException('Access out of bounds') is thrown, signaling more data is needed.
Source
Thrown at independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/multipart/QuarkusMultipartResponseDecoder.java:640
*/
private static void skipControlCharacters(ByteBuf undecodedChunk) {
if (!undecodedChunk.hasArray()) {
try {
skipControlCharactersStandard(undecodedChunk);
} catch (IndexOutOfBoundsException e1) {
throw new NotEnoughDataDecoderException(e1);
}
return;
}
QuarkusHttpPostBodyUtil.SeekAheadOptimize sao = new QuarkusHttpPostBodyUtil.SeekAheadOptimize(undecodedChunk);
while (sao.pos < sao.limit) {
char c = (char) (sao.bytes[sao.pos++] & 0xFF);
if (!Character.isISOControl(c) && !Character.isWhitespace(c)) {
sao.setReadPosition(1);
return;
}
}
throw new NotEnoughDataDecoderException("Access out of bounds");
}
private static void skipControlCharactersStandard(ByteBuf undecodedChunk) {
for (;;) {
char c = (char) undecodedChunk.readUnsignedByte();
if (!Character.isISOControl(c) && !Character.isWhitespace(c)) {
undecodedChunk.readerIndex(undecodedChunk.readerIndex() - 1);
break;
}
}
}
/**
* Find the next Multipart Delimiter
*
* @param delimiter
* delimiter to find
* @param dispositionStatusView on GitHub (pinned to e1c734241f)
Solutions
- Accumulate chunks and only offer complete buffers when possible; treat NotEnoughDataDecoderException as 'need more data'
- Check that the response is not truncated by the server/proxy (Content-Length vs actual bytes)
- Ensure the decoder is fed the full HttpContent for each chunk, not a stale view
- If the error persists on a complete response, inspect for corrupted boundary lines
Example fix
// before
try {
decoder.offer(chunk);
} catch (NotEnoughDataDecoderException e) { /* treated as fatal */ }
// after
try {
decoder.offer(chunk);
} catch (NotEnoughDataDecoderException e) {
// normal: wait for the next chunk before continuing
} Defensive patterns
Strategy: try-catch
Try / catch
try { decoder.offer(chunk); } catch (NotEnoughDataDecoderException e) { /* not fatal: buffer and wait for more data */ pending.add(chunk); } Prevention
- Treat NotEnoughDataDecoderException as a signal for more data, not an error
- Avoid delivering tiny fragments when you can coalesce chunks
- Verify response completeness (Content-Length vs received bytes)
When it happens
Trigger: findMultipartDelimiter or findMultipartDisposition is invoked while the current undecoded chunk contains only whitespace/control bytes (or is exhausted), i.e. the boundary line hasn't arrived yet.
Common situations: Offering chunks one byte at a time (slow/fragmented responses); the client feeding partial buffers without accumulating; a truncated response ending in whitespace.
Related errors
- Cannot create a Encoder if request is a TRACE
- Needs a boundary value
- No 'Content-Type' header present.
- Illegal charset in multipart response Content-Type (wrapped)
- Unable to parse multipart response - No delimiter specified
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/6b0ca82b9ea02bd9.
Report an issue: GitHub.