chocolatey/choco · warning · TimeoutException

Timeout waiting for exclusive access to value.

Error message

Timeout waiting for exclusive access to value.

What it means

Thrown by the GlobalMutex constructor when WaitOne returns false within the supplied timeout, meaning another process held the named global mutex for the entire wait window. The mutex is used to serialize access to a shared resource (e.g. a package install lock); the TimeoutException signals that exclusive access could not be acquired in time.

Source

Thrown at src/chocolatey/infrastructure/synchronization/GlobalMutex.cs:65

            _mutex.SetAccessControl(securitySettings);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="GlobalMutex"/> class.
        /// </summary>
        /// <param name="timeOut">The time out in milliseconds.</param>
        /// <exception cref="System.TimeoutException">Timeout waiting for exclusive access to value.</exception>
        private GlobalMutex(int timeOut)
        {
            InitMutex();
            try
            {
                this.Log().Trace("Waiting on the mutex handle for {0} milliseconds".FormatWith(timeOut));
                _hasHandle = _mutex.WaitOne(timeOut < 0 ? Timeout.Infinite : timeOut, exitContext: false);

                if (_hasHandle == false)
                {
                    throw new TimeoutException("Timeout waiting for exclusive access to value.");
                }
            }
            catch (AbandonedMutexException)
            {
                _hasHandle = true;
            }
        }

        /// <summary>
        /// Enters the Global Mutex
        /// </summary>
        /// <param name="action">The action to perform.</param>
        /// <param name="timeout">The timeout in milliseconds.</param>
        public static void Enter(Action action, int timeout)
        {

            if (Platform.GetPlatform() == PlatformType.Windows)
            {

View on GitHub (pinned to 0d5abdd10c)

Solutions

  1. Wait for the other Chocolatey process to finish, or increase the configured mutex timeout to accommodate contention.
  2. Identify and terminate any orphaned/hung Chocolatey process holding the lock (AbandonedMutexException would normally be caught, but a live holder will not be).
  3. Avoid running multiple package operations against the same target simultaneously; serialize them in your automation.

Example fix

// before
using (new GlobalMutex(timeOut: 5000)) { DoWork(); } // throws on contention

// after
using (new GlobalMutex(timeOut: 60000)) { DoWork(); } // or serialize callers
Defensive patterns

Strategy: retry

Validate before calling

// Best-effort pre-check: ensure no other choco process is running before acquiring the mutex.
var otherChoco = Process.GetProcessesByName("choco").Where(p => p.Id != Process.GetCurrentProcess().Id).ToList();
if (otherChoco.Count > 0)
    logger.Warn(otherChoco.Count + " other choco process(es) detected; mutex contention likely.");

Try / catch

for (int attempt = 0; attempt < 3; attempt++)
{
    try
    {
        using (var mtx = new GlobalMutex(timeOut: 30000))
        {
            DoCriticalWork();
        }
        break;
    }
    catch (TimeoutException ex) when (ex.Message.Contains("exclusive access"))
    {
        logger.Warn("Mutex timeout on attempt " + (attempt + 1) + "; retrying after backoff.");
        if (attempt == 2) throw;
    }
}

Prevention

When it happens

Trigger: Constructing a GlobalMutex with a finite timeOut while another Chocolatey process (or a hung previous instance) owns the underlying named mutex. WaitOne times out and _hasHandle stays false, raising TimeoutException. A negative timeout maps to Infinite and will not time out.

Common situations: Concurrent choco invocations contending for the same lock; a crashed/abandoned-but-not-yet-reaped process still holding the mutex; an antivirus or backup job locking the resource Chocolatey serializes on; an undersized timeout under heavy load.

Understand the failure class


AI-assisted analysis of chocolatey/choco@0d5abdd10c (2026-08-13). Data as JSON: /api/errors/480ee4f5eb77751b. Report an issue: GitHub.