TheAlgorithms/Java · error · IllegalStateException
Queue is empty, cannot remove element
Error message
Queue is empty, cannot remove element
What it means
Thrown by Queue.remove() as an IllegalStateException when isEmpty() (nItems == 0). The array ring buffer cannot return a front element it does not hold, so removal from an empty queue is rejected. This is the standard FIFO underflow guard.
Source
Thrown at src/main/java/com/thealgorithms/datastructures/queues/Queue.java:69
if (isFull()) {
return false;
}
rear = (rear + 1) % maxSize;
queueArray[rear] = element;
nItems++;
return true;
}
/**
* Removes and returns the element from the front of the queue.
*
* @return The element removed from the front of the queue.
* @throws IllegalStateException if the queue is empty.
*/
@SuppressWarnings("unchecked")
public T remove() {
if (isEmpty()) {
throw new IllegalStateException("Queue is empty, cannot remove element");
}
T removedElement = (T) queueArray[front];
queueArray[front] = null; // Optional: Clear the reference for garbage collection
front = (front + 1) % maxSize;
nItems--;
return removedElement;
}
/**
* Checks the element at the front of the queue without removing it.
*
* @return Element at the front of the queue.
* @throws IllegalStateException if the queue is empty.
*/
@SuppressWarnings("unchecked")
public T peekFront() {
if (isEmpty()) {
throw new IllegalStateException("Queue is empty, cannot peek front");View on GitHub (pinned to fdfb9a395b)
Solutions
- Guard with isEmpty() before remove() and skip or wait when empty.
- Drive removal loops by nItems/size rather than an external counter that can overshoot.
- Catch IllegalStateException when an empty queue is an expected branch.
Example fix
// before
T v = queue.remove(); // throws when empty
// after
T v = null;
if (!queue.isEmpty()) {
v = queue.remove();
} Defensive patterns
Strategy: validation
Validate before calling
if (!queue.isEmpty()) {
T v = queue.remove();
} Type guard
null
Try / catch
null
Prevention
- isEmpty()-guard every remove().
- Use the queue's own size/empty state to bound drain loops.
- Wrap remove to return Optional so callers handle the empty case in the type.
When it happens
Trigger: Calling remove() before any insert(), or calling remove() more times than insert(). Also after the queue is fully drained, any further remove() throws.
Common situations: Consumer outpacing producer; loop bounds larger than the number of inserts; draining logic with an extra pop after exhaustion; request handler removing from a shared queue with no pending work.
Related errors
- Queue is empty
- Queue is empty
- Queue is empty, cannot peek front
- Queue is empty, cannot peek rear
- Queue is empty
AI-assisted analysis of TheAlgorithms/Java@fdfb9a395b (2026-08-13).
Data as JSON: /api/errors/56abaf38e09892b9.
Report an issue: GitHub.