argoproj/argo-workflows · error
invalid lock kind %s when initializing mutex
Error message
invalid lock kind %s when initializing mutex
What it means
initializeMutex validates that the resolved lock kind is one of the supported kinds (mutex/configmap or database). If a sync resource resolves to an unrecognized kind, initialization is rejected with this error. It guards against malformed or future-unknown lock kind declarations.
Source
Thrown at workflow/sync/sync_manager.go:878
return nil, fmt.Errorf("invalid lock kind %s when initializing semaphore", lock.getKind())
}
}
func (sm *Manager) initializeMutex(ctx context.Context, mutexName string) (semaphore, error) {
lock, err := DecodeLockName(ctx, mutexName)
if err != nil {
return nil, err
}
switch lock.getKind() {
case lockKindMutex:
return newInternalMutex(mutexName, sm.nextWorkflow), nil
case lockKindDatabase:
if sm.dbInfo.SessionProxy == nil {
return nil, fmt.Errorf("database session is not available for mutex %s", mutexName)
}
return newDatabaseMutex(mutexName, lock.getDBKey(), sm.nextWorkflow, sm.dbInfo), nil
default:
return nil, fmt.Errorf("invalid lock kind %s when initializing mutex", lock.getKind())
}
}
func (sm *Manager) backgroundNotifier(ctx context.Context, period *int) {
sm.log.WithField("pollInterval", syncdb.SecondsToDurationWithDefault(period, syncdb.DefaultDBHeartbeatSeconds)).
Info(ctx, "Starting background notification for sync locks")
go wait.UntilWithContext(ctx, func(_ context.Context) {
sm.lock.Lock()
for _, lock := range sm.syncLockMap {
lock.probeWaiting(ctx)
}
sm.lock.Unlock()
},
syncdb.SecondsToDurationWithDefault(period, syncdb.DefaultDBPollSeconds),
)
}
// dbControllerHeartbeat does periodic deadmans switch updates to the controller stateView on GitHub (pinned to 35bff19146)
Solutions
- Correct the lock kind in the sync ConfigMap to a supported value ('configmap' for mutex/semaphore or 'database')
- Re-apply the sync ConfigMap from a known-good example and verify with kubectl get configmap
- Check controller version compatibility — kind strings may differ across Argo Workflows versions
Example fix
// before (sync ConfigMap) kind: databse // after kind: database
Defensive patterns
Strategy: validation
Validate before calling
allowed := map[string]bool{"configmap": true, "database": true}
if !allowed[strings.ToLower(lockKind)] {
return fmt.Errorf("sync lock kind %q not supported", lockKind)
} Type guard
func isKnownLockKind(k string) bool {
return k == "configmap" || k == "database"
} Try / catch
if err != nil && strings.Contains(err.Error(), "invalid lock kind") {
log.Fatalf("fix sync ConfigMap kind field: %v", err)
} Prevention
- Copy lock kind values only from official Argo docs/examples
- Validate sync ConfigMaps in CI with the WorkflowSpec schema
- Avoid hand-editing sync ConfigMaps in production
When it happens
Trigger: A sync ConfigMap entry declares a kind value that is neither 'mutex' (configmap) nor 'database', and a workflow tries to acquire it through prepAcquire -> initializeMutex.
Common situations: Typo in the lock kind field in a sync ConfigMap (e.g. 'databse', 'semaphre'); hand-edited or older-version sync ConfigMaps using a kind string no longer supported; copying examples with invalid kind values.
Related errors
- requested configuration is invalid: %w
- database session is not available for mutex %s
- malformed workflow template parameter "%s": valueFrom is nil
- maxRetries cannot be less than 0
- baseDelay cannot be less than 0
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/84d01a9850abeb91.
Report an issue: GitHub.