OrchardCMS/OrchardCore · error · TimeoutException

Couldn't acquire a lock to update the sitemap within

Error message

Couldn't acquire a lock to update the sitemap within {timeout.Seconds} seconds.

What it means

DefaultSitemapUpdateHandler.TryUpdateSitemapAsync acquires a distributed lock (SITEMAPS_UPDATE_LOCK) with a 20-second timeout before rebuilding sitemaps. If the lock cannot be acquired within that window — because another sitemap update is still running — it throws TimeoutException to prevent concurrent/overlapping sitemap rebuilds.

Solutions

  1. Reduce sitemap size/complexity (page via sitemap index, limit entries) so rebuilds finish under 20 seconds.
  2. Retry the update after a delay — the error means the lock was busy, so re-trigger the sitemap rebuild.
  3. Ensure only one node/rebuild process updates sitemaps at a time (stagger background tasks, avoid simultaneous saves).
  4. Check whether another process is stuck holding the lock (hanging rebuild) and restart it; investigate slow sitemap builders.

Example fix

// before (caller)
await _sitemapManager.TryUpdateSitemapAsync(sitemapId);
// after (caller with retry)
try { await _sitemapManager.TryUpdateSitemapAsync(sitemapId); }
catch (TimeoutException) { _logger.LogWarning("Sitemap update locked; will retry."); await Task.Delay(5000); /* retry */ }
Defensive patterns

Strategy: retry

Validate before calling

// no pre-call validation possible; check lock contention before retrying
var recent = await _distributedLockService.TryAcquireLockAsync("SITEMAPS_UPDATE_LOCK", TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(1));
if (!recent.locked) logger.LogWarning("Sitemap update lock is currently held; defer the rebuild.");

Try / catch

try {
  await sitemapManager.TryUpdateSitemapAsync(sitemapId);
} catch (TimeoutException ex) when (ex.Message.Contains("sitemap")) {
  await Task.Delay(TimeSpan.FromSeconds(30));
  // retry once, or enqueue a background rebuild
}

Prevention

When it happens

Trigger: Two or more sitemap update requests overlap (e.g. saving a sitemap while a scheduled/background rebuild holds the lock for more than 20 seconds); large sitemap generation exceeding the lock timeout; multi-node farms contending for the lock.

Common situations: Multi-server Orchard deployments with a shared distributed lock; very large sitemaps (tens of thousands of URLs) taking longer than 20s to build; rapid successive saves to sitemap entries triggering rebuilds.

Understand the failure class

Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.

Related errors


AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13). Data as JSON: /api/errors/422fb8f24db477bb. Report an issue: GitHub.

Appendix: source

Thrown at src/OrchardCore.Modules/OrchardCore.Sitemaps/Handlers/DefaultSitemapUpdateHandler.cs:28

    public DefaultSitemapUpdateHandler(
        IEnumerable<ISitemapTypeUpdateHandler> sitemapTypeUpdateHandlers,
        IDistributedLock distributedLock)
    {
        _sitemapTypeUpdateHandlers = sitemapTypeUpdateHandlers;
        _distributedLock = distributedLock;
    }

    public async Task UpdateSitemapAsync(SitemapUpdateContext context)
    {
        // Doing the update in a synchronized way makes sure that two simultaneous content item updates don't cause
        // a ConcurrencyException due to the same sitemap document being updated.

        var timeout = TimeSpan.FromMilliseconds(20_000);
        (var locker, var locked) = await _distributedLock.TryAcquireLockAsync("SITEMAPS_UPDATE_LOCK", timeout, timeout);

        if (!locked)
        {
            throw new TimeoutException($"Couldn't acquire a lock to update the sitemap within {timeout.Seconds} seconds.");
        }

        using (locker)
        {
            foreach (var sitemapTypeUpdateHandler in _sitemapTypeUpdateHandlers)
            {
                await sitemapTypeUpdateHandler.UpdateSitemapAsync(context);
            }
        }
    }
}

View on GitHub (pinned to 4306c0717f)