abpframework/abp · error · AbpException

The distributed lock name '{lockName}' is already used by an

Error message

The distributed lock name '{lockName}' is already used by another background job worker. Each worker must have a unique lock name.

What it means

Thrown by AbpBackgroundJobWorkerOptions.AddDedicatedWorker when the supplied lockName equals the global DistributedLockName or matches the LockName of any existing BackgroundJobWorkerConfiguration. Each dedicated worker needs a unique distributed lock so workers don't contend under the same lock identity.

Source

Thrown at framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobWorkerOptions.cs:144

    /// <param name="jobArgsTypes">The job argument types handled exclusively by this worker.</param>
    public AbpBackgroundJobWorkerOptions AddDedicatedWorker(string lockName, params Type[] jobArgsTypes)
    {
        Check.NotNullOrEmpty(jobArgsTypes, nameof(jobArgsTypes));

        var configuration = new BackgroundJobWorkerConfiguration(lockName, jobArgsTypes.Distinct().ToArray());

        var duplicateType = configuration.JobArgsTypes.FirstOrDefault(
            type => WorkerConfigurations.Any(c => c.JobArgsTypes.Contains(type)));
        if (duplicateType != null)
        {
            throw new AbpException(
                $"The background job args type '{duplicateType.FullName}' is already assigned to a dedicated worker. " +
                $"Each job type can be handled by only one dedicated worker.");
        }

        if (lockName == DistributedLockName || WorkerConfigurations.Any(c => c.LockName == lockName))
        {
            throw new AbpException(
                $"The distributed lock name '{lockName}' is already used by another background job worker. " +
                $"Each worker must have a unique lock name.");
        }

        WorkerConfigurations.Add(configuration);
        return this;
    }

    public AbpBackgroundJobWorkerOptions AddDedicatedWorker<TArgs>(string lockName)
    {
        return AddDedicatedWorker(lockName, typeof(TArgs));
    }

    public AbpBackgroundJobWorkerOptions AddDedicatedWorker<TArgs1, TArgs2>(string lockName)
    {
        return AddDedicatedWorker(lockName, typeof(TArgs1), typeof(TArgs2));
    }

View on GitHub (pinned to 7ed43b1931)

Solutions

  1. Give each dedicated worker a distinct, descriptive lock name.
  2. Avoid reusing the global DistributedLockName value for any worker.
  3. Audit all AddDedicatedWorker call sites and deduplicate lock names.
  4. Derive lock names from the job type or feature to avoid collisions.

Example fix

// before
options.AddDedicatedWorker("jobs-lock", typeof(EmailJobArgs));
options.AddDedicatedWorker("jobs-lock", typeof(SmsJobArgs)); // throws
// after
options.AddDedicatedWorker("email-jobs-lock", typeof(EmailJobArgs));
options.AddDedicatedWorker("sms-jobs-lock", typeof(SmsJobArgs));
Defensive patterns

Strategy: validation

Validate before calling

var usedLocks = options.WorkerConfigurations.Select(c => c.LockName)
    .Append(options.DistributedLockName).ToHashSet();
if (usedLocks.Contains(lockName)) { /* pick a distinct name */ }

Type guard

null

Try / catch

try { options.AddDedicatedWorker(lockName, types); }
catch (AbpException ex) when (ex.Message.Contains("unique lock name"))
{ /* choose a different lock name */ }

Prevention

When it happens

Trigger: Calling AddDedicatedWorker(lockName, ...) with a lockName that is already in use - either the global DistributedLockName or another worker's LockName.

Common situations: Two workers registered with the same hard-coded lock name; a lock name colliding with the default DistributedLockName; refactoring that copied a worker registration and forgot to rename the lock; multiple modules choosing generic lock names.

Related errors


AI-assisted analysis of abpframework/abp@7ed43b1931 (2026-08-13). Data as JSON: /api/errors/8071841384f3197c. Report an issue: GitHub.