TheAlgorithms/Java · error · IllegalStateException
Queue is empty
Error message
Queue is empty
What it means
Thrown by CircularQueue.deQueue() as an IllegalStateException when isEmpty() is true (currentSize == 0). The queue refuses to return a front element it does not have. This is the standard underflow guard for a bounded ring buffer.
Source
Thrown at src/main/java/com/thealgorithms/datastructures/queues/CircularQueue.java:94
throw new IllegalStateException("Queue is full");
}
if (isEmpty()) {
beginningOfQueue = 0;
}
topOfQueue = (topOfQueue + 1) % size;
array[topOfQueue] = value;
currentSize++;
}
/**
* Removes and returns the element at the front of the queue.
*
* @return the element at the front of the queue
* @throws IllegalStateException if the queue is empty
*/
public T deQueue() {
if (isEmpty()) {
throw new IllegalStateException("Queue is empty");
}
T removedValue = array[beginningOfQueue];
array[beginningOfQueue] = null; // Optional: Nullify to help garbage collection
beginningOfQueue = (beginningOfQueue + 1) % size;
currentSize--;
if (isEmpty()) {
beginningOfQueue = -1;
topOfQueue = -1;
}
return removedValue;
}
/**
* Returns the element at the front of the queue without removing it.
*
* @return the element at the front of the queue
* @throws IllegalStateException if the queue is empty
*/View on GitHub (pinned to fdfb9a395b)
Solutions
- Call isEmpty() (or isFull() check) before deQueue() and skip or wait when the queue is empty.
- Track enqueued vs dequeued counts in the caller to prevent over-dequeue in loops.
- Wrap the call in try/catch(IllegalStateException) if the empty case should be handled as a normal control-flow signal.
- For concurrent use, replace with a blocking queue so the consumer waits instead of throwing.
Example fix
// before
T v = queue.deQueue(); // throws when empty
// after
T v = null;
if (!queue.isEmpty()) {
v = queue.deQueue();
} Defensive patterns
Strategy: validation
Validate before calling
if (!queue.isEmpty()) {
T v = queue.deQueue();
} Type guard
null
Try / catch
null
Prevention
- Check isEmpty() before every deQueue on a bounded ring buffer.
- Drive drain loops by a count derived from the queue, not an external loop variable.
- For concurrent pipelines, prefer a blocking queue so the consumer waits instead of throwing.
When it happens
Trigger: Calling deQueue() on a freshly constructed CircularQueue, or calling deQueue() more times than enQueue() has been called. Also triggered after deleteQueue() resets state if the instance is still referenced.
Common situations: Consumer draining a queue the producer has not yet filled; off-by-one loop where the dequeue count exceeds the enqueue count; draining logic running once more after the queue is exhausted; shared queue where one consumer races ahead of production.
Related errors
- Queue is empty
- Queue is empty, cannot remove element
- 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/b9a9937928d3b121.
Report an issue: GitHub.