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 state

View on GitHub (pinned to 35bff19146)

Solutions

  1. Correct the lock kind in the sync ConfigMap to a supported value ('configmap' for mutex/semaphore or 'database')
  2. Re-apply the sync ConfigMap from a known-good example and verify with kubectl get configmap
  3. 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

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


AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03). Data as JSON: /api/errors/84d01a9850abeb91. Report an issue: GitHub.