Cysharp/UniTask · error · TimeoutException

Exceed Timeout:

Error message

Exceed Timeout:

What it means

Thrown by UniTask.Timeout (non-generic) when the timeout delay wins the WhenAny race (winArgIndex == 1) before the wrapped task completes. This is the intended timeout behavior: the task did not finish within the specified TimeSpan, so UniTask cancels the task's CancellationTokenSource (if provided) and throws TimeoutException. The task itself is cancelled as a side effect.

Source

Thrown at src/UniTask/Assets/Plugins/UniTask/Runtime/UniTaskExtensions.cs:401

                (winArgIndex, taskResultIsCanceled, _) = await UniTask.WhenAny(task.SuppressCancellationThrow(), timeoutTask);
            }
            catch
            {
                delayCancellationTokenSource.Cancel();
                delayCancellationTokenSource.Dispose();
                throw;
            }

            // timeout
            if (winArgIndex == 1)
            {
                if (taskCancellationTokenSource != null)
                {
                    taskCancellationTokenSource.Cancel();
                    taskCancellationTokenSource.Dispose();
                }

                throw new TimeoutException("Exceed Timeout:" + timeout);
            }
            else
            {
                delayCancellationTokenSource.Cancel();
                delayCancellationTokenSource.Dispose();
            }

            if (taskResultIsCanceled)
            {
                Error.ThrowOperationCanceledException();
            }
        }

        public static async UniTask<T> Timeout<T>(this UniTask<T> task, TimeSpan timeout, DelayType delayType = DelayType.DeltaTime, PlayerLoopTiming timeoutCheckTiming = PlayerLoopTiming.Update, CancellationTokenSource taskCancellationTokenSource = null)
        {
            var delayCancellationTokenSource = new CancellationTokenSource();
            var timeoutTask = UniTask.Delay(timeout, delayType, timeoutCheckTiming, delayCancellationTokenSource.Token).SuppressCancellationThrow();

View on GitHub (pinned to ceac8d6946)

Solutions

  1. Increase the timeout value to accommodate expected latency
  2. Investigate and optimize the wrapped task to complete faster
  3. Use TimeoutWithoutException if you want to handle the timeout as a boolean rather than an exception
  4. Catch TimeoutException explicitly and provide a fallback or retry

Example fix

// before
await someNetworkCall.Timeout(TimeSpan.FromSeconds(1));

// after (option 1: longer timeout)
await someNetworkCall.Timeout(TimeSpan.FromSeconds(10));

// after (option 2: suppress)
bool timedOut = await someNetworkCall.TimeoutWithoutException(TimeSpan.FromSeconds(5));
if (timedOut) { /* fallback */ }
Defensive patterns

Strategy: try-catch

Try / catch

try
{
    await task.Timeout(timeout);
}
catch (TimeoutException ex)
{
    // handle timeout: fallback, retry, or log
    Debug.LogWarning($"Task timed out: {ex.Message}");
}

Prevention

When it happens

Trigger: Calling await task.Timeout(TimeSpan.FromSeconds(5)) where the task takes longer than 5 seconds. Network requests, file I/O, or long-running computations wrapped with .Timeout() that exceed the configured deadline.

Common situations: Slow or unresponsive external systems (servers, databases). Network latency spikes. Deadlocks or contention causing tasks to stall. Configuring an unrealistically short timeout. Tasks that block on locks or never-complete awaits.

Understand the failure class

Related errors


AI-assisted analysis of Cysharp/UniTask@ceac8d6946 (2026-08-13). Data as JSON: /api/errors/561688cb304688c2. Report an issue: GitHub.