google/ExoPlayer · warning · PriorityTaskManager.PriorityTooLowException
Priority too low [priority=%d, highest=%d]
Error message
Priority too low [priority=%d, highest=%d]
What it means
PriorityTaskManager.proceedOrThrow(priority) throws PriorityTooLowException when the caller's priority does not exactly equal the manager's current highest_priority — meaning some other registered task is running at a higher priority and lower-priority work must not proceed. ExoPlayer uses this for codec/derasterizer vs network/download contention: network tasks call proceedOrThrow in a loop, backing off until their priority becomes the highest. It extends IOException, signaling a transient, retryable condition rather than a hard failure.
Source
Thrown at library/common/src/main/java/com/google/android/exoplayer2/util/PriorityTaskManager.java:106
* @param priority The priority of the task.
* @return Whether the task is allowed to proceed.
*/
public boolean proceedNonBlocking(int priority) {
synchronized (lock) {
return highestPriority == priority;
}
}
/**
* A throwing variant of {@link #proceed(int)}.
*
* @param priority The priority of the task.
* @throws PriorityTooLowException If the task is not allowed to proceed.
*/
public void proceedOrThrow(int priority) throws PriorityTooLowException {
synchronized (lock) {
if (highestPriority != priority) {
throw new PriorityTooLowException(priority, highestPriority);
}
}
}
/**
* Unregister a task.
*
* @param priority The priority of the task.
*/
public void remove(int priority) {
synchronized (lock) {
queue.remove(priority);
highestPriority = queue.isEmpty() ? Integer.MIN_VALUE : Util.castNonNull(queue.peek());
lock.notifyAll();
}
}
}
View on GitHub (pinned to dd430f7053)
Solutions
- Retry or block instead of failing: catch PriorityTooLowException and either wait/backoff-retry, or simply use proceed(priority) which blocks until the priority is highest — that is the intended API for long tasks
- Ensure priorities are consistent with registration: proceed/proceedOrThrow must be called with the same priority value the task registered with via add(priority)
- Re-check ordering around cancelation: always call remove(priority) in finally so highest_priority falls and other tasks can proceed
- For custom task types, register with C.PRIORITY_* constants that order sensibly vs playback so downloads yield but still run when idle
Example fix
// before
manager.proceedOrThrow(C.PRIORITY_BACKGROUND); // throws while playback active
// after
manager.proceed(C.PRIORITY_BACKGROUND); // blocks until allowed
try {
// task body
} finally {
manager.remove(C.PRIORITY_BACKGROUND);
} Defensive patterns
Strategy: retry
Validate before calling
if (!manager.isRegisteredPriorityCurrent(priority)) { /* library-dependent; in practice: catch and retry */ } Try / catch
while (true) {
try { manager.proceedOrThrow(priority); break; }
catch (PriorityTooLowException e) {
// back off and retry, or switch to manager.proceed(priority) which blocks
}
} Prevention
- Prefer proceed(priority) (blocking) for long tasks; proceedOrThrow is for cooperative loops that yield
- Always pair add(priority) ... finally remove(priority)
- Register with the C.PRIORITY_* constants so ordering vs playback is deterministic
When it happens
Trigger: A task registered at priority N calls proceedOrThrow(N) while playback (registered higher, e.g. C.PRIORITY_PLAYBACK) holds highest_priority; typical flow is PriorityTaskManager.proceed(N) which blocks, but code paths like CacheDataSource/HttpDataSource interruption handling call proceedOrThrow and expect PriorityTooLowException to pause downloading.
Common situations: Custom DownloadManager or CacheDataSource integrations where download priority (C.PRIORITY_BACKGROUND) is below active playback priority; multiple simultaneous streams re-prioritizing; calling proceedOrThrow while another thread's add() raised highest_priority between your add() and proceedOrThrow().
Related errors
- Cannot read frame at position ${lastDecodePosition}
- Couldn't create {baseName}
- Player is accessed on the wrong thread. Current thread: '%s'
AI-assisted analysis of google/ExoPlayer@dd430f7053 (2026-08-14).
Data as JSON: /api/errors/f40aa17064e18e7d.
Report an issue: GitHub.