apache/hadoop · error · IllegalArgumentException
Buffer has no data left.
Error message
Buffer has no data left.
What it means
doIO(ByteBuffer, ops) is the core transfer loop of SocketIOWithTimeout. It requires buf.hasRemaining(); a buffer with position == limit has nothing to read into or write out, which is always a caller bug, so it throws IllegalArgumentException up front (the source even muses 'or should we just return 0?').
Source
Thrown at hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/net/SocketIOWithTimeout.java:131
* It waits up to the specified timeout. If the channel is
* not read before the timeout, SocketTimeoutException is thrown.
*
* @param buf buffer for IO
* @param ops Selection Ops used for waiting. Suggested values:
* SelectionKey.OP_READ while reading and SelectionKey.OP_WRITE while
* writing.
*
* @return number of bytes read or written. negative implies end of stream.
* @throws IOException
*/
int doIO(ByteBuffer buf, int ops) throws IOException {
/* For now only one thread is allowed. If user want to read or write
* from multiple threads, multiple streams could be created. In that
* case multiple threads work as well as underlying channel supports it.
*/
if (!buf.hasRemaining()) {
throw new IllegalArgumentException("Buffer has no data left.");
//or should we just return 0?
}
while (buf.hasRemaining()) {
if (closed) {
return -1;
}
try {
int n = performIO(buf);
if (n != 0) {
// successful io or an error.
return n;
}
} catch (IOException e) {
if (!channel.isOpen()) {
closed = true;
}View on GitHub (pinned to 2add963021)
Solutions
- Reset the buffer each iteration: clear() before reads, flip() or rewind() before writes as appropriate
- Skip or return early when !buf.hasRemaining() instead of calling the API
- Unit-test the loop against partial reads/writes so positions are always valid
Example fix
// before
while (!done) { in.read(buf); } // buf never cleared -> throws once drained
// after
while (!done) {
buf.clear();
int n = in.read(buf);
if (n < 0) break;
buf.flip();
consume(buf);
} Defensive patterns
Strategy: validation
Validate before calling
if (!buf.hasRemaining()) {
buf.clear(); // or skip the call if there is nothing to transfer
}
in.read(buf); Type guard
static boolean bufferReadyForIo(ByteBuffer buf) {
return buf != null && buf.hasRemaining();
} Prevention
- clear()/flip() the buffer on every loop iteration
- Add assertions for buffer positions in tests that exercise partial reads/writes
When it happens
Trigger: Calling read(ByteBuffer)/write(ByteBuffer) on SocketInputStream/SocketOutputStream with an exhausted buffer — typically forgetting buffer.clear() after draining a read, or flip()/rewind before a write, inside a loop.
Common situations: ByteBuffer position/limit mismanagement in NIO read/write loops; reusing one shared buffer across iterations without resetting; partial-read loops that keep calling with the same consumed buffer.
Related errors
- Channel is null. Check how the channel or socket is created.
- Channel should be a SelectableChannel
- {} millis timeout while waiting for channel to be ready for
- Interrupted while waiting for IO on channel {}. Total timeou
- getXAttrs on path `{}' is not within a mount point
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/191a0823a527e92b.
Report an issue: GitHub.