argoproj/argo-workflows · error
failed to get current lock holders: %w
Error message
failed to get current lock holders: %w
What it means
After acquiring, tryAcquireImpl reads the authoritative holder list via getCurrentLockHolders to reconcile workflow status; a backend error here aborts the acquire with 'failed to get current lock holders'. Lock state is unknown, so the operation fails rather than risking an inconsistent double-acquire.
Source
Thrown at workflow/sync/sync_manager.go:657
var newly []*acquiredLock
for i, lockKey := range lockKeys {
lock := sm.syncLockMap[lockKey]
var acquired bool
var acquireErr error
acquired, msg, acquireErr = lock.tryAcquire(ctx, holderKey, tx)
if acquireErr != nil {
// Surface the underlying error so callers (e.g. TryAcquire's
// retry loop) can decide whether it is retryable. Transient
// database errors like PostgreSQL SQLSTATE 40001 must reach
// the retry detector untouched.
return false, false, "", failedLockName, nil, acquireErr
}
if !acquired {
return false, false, "", failedLockName, nil, fmt.Errorf("bug: failed to acquire something that should have been checked: %s", msg)
}
currentHolders, err := sm.getCurrentLockHolders(ctx, lockKey)
if err != nil {
return false, false, "", failedLockName, nil, fmt.Errorf("failed to get current lock holders: %w", err)
}
if wf.Status.Synchronization.GetStatus(syncItems[i].getType()).LockAcquired(holderKey, lockKey, currentHolders) {
updated = true
newly = append(newly, &acquiredLock{name: lockKey, kind: syncItems[i].getType()})
}
}
return true, updated, msg, failedLockName, newly, nil
default: // Not all acquirable
updated := false
for i, lockKey := range lockKeys {
currentHolders, err := sm.getCurrentLockHolders(ctx, lockKey)
if err != nil {
return false, false, "", failedLockName, nil, fmt.Errorf("failed to get current lock holders: %w", err)
}
if wf.Status.Synchronization.GetStatus(syncItems[i].getType()).LockWaiting(holderKey, lockKey, currentHolders) {
updated = true
}
}View on GitHub (pinned to 35bff19146)
Solutions
- Check the wrapped cause: ConfigMap RBAC vs DB connectivity
- Retry the operation — often transient (backend hiccup)
- Verify the controller's RBAC allows reading sync ConfigMaps
- Check DB health for database-backed locks
Defensive patterns
Strategy: retry
Try / catch
if err != nil && strings.Contains(err.Error(), "failed to get current lock holders") {
if utilerrors.IsTransientErr(ctx, err) { time.Sleep(backoff); retry() }
} Prevention
- Grant the controller get/update on sync ConfigMaps
- Configure retry/backoff around TryAcquire in operator loops
- Monitor sync backend (DB/API server) health
When it happens
Trigger: getCurrentLockHolders errors after a successful individual acquire — ConfigMap read/decode failure, DB query failure, or transient backend unavailability for that lockKey.
Common situations: API-server throttling or RBAC denial on ConfigMap reads; Postgres/MySQL outage for DB-backed semaphores; oversized/corrupted sync ConfigMap.
Related errors
- synchronization database session is not available
- database session is not available for semaphore %s
- failed to initialize semaphore %s: %w
- cannot re-establish %s %q held by workflow %s/%s at startup:
- cannot acquire lock from nil Synchronization
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/caf5e76f82557854.
Report an issue: GitHub.