argoproj/argo-workflows · error
failed to initialize semaphore %s: %w
Error message
failed to initialize semaphore %s: %w
What it means
newInternalSemaphore resolves the semaphore's limit via limitGetter.get before first use. If that fetch errors, the error is wrapped as 'failed to initialize semaphore' rather than silently defaulting the limit to 0 — a genuine failure stays distinguishable from an approval-gate semaphore that legitimately starts at limit 0.
Source
Thrown at workflow/sync/semaphore.go:47
name: name,
lockType: lockTypeSemaphore,
}
sem := &prioritySemaphore{
name: name,
limitGetter: newCachedLimit(configMapGetter, syncLimitCacheTTL),
pending: &priorityQueue{itemByKey: make(map[string]*item)},
semaphore: sema.NewWeighted(int64(0)),
lockHolder: make(map[string]bool),
nextWorkflow: nextWorkflow,
logger: logger.get,
}
// Resolve the limit directly through limitGetter rather than getLimit(), since
// getLimit() falls back to the cache's zero-value on a fetch error, which would
// make a genuine error indistinguishable from a semaphore that legitimately
// starts at limit 0 (e.g. an "approval gate" held closed until raised).
limit, changed, err := sem.limitGetter.get(ctx, name)
if err != nil {
return nil, fmt.Errorf("failed to initialize semaphore %s: %w", name, err)
}
if changed && !sem.resize(ctx, limit) {
return nil, fmt.Errorf("failed to size semaphore %s to limit %d", name, limit)
}
return sem, nil
}
func (s *prioritySemaphore) getLimit(ctx context.Context) int {
limit, changed, err := s.limitGetter.get(ctx, s.name)
if err != nil {
// Fall back to the last known limit (returned by the cache alongside
// the error). Returning 0 here would make release() treat a transient
// fetch failure as a downward resize and permanently leak a slot.
s.logger(ctx).WithError(err).WithFields(logging.Fields{
"name": s.name,
"fallbackLimit": limit,
}).Error(ctx, "failed to get limit for semaphore, using last known limit")
return limitView on GitHub (pinned to 35bff19146)
Solutions
- Verify the semaphore ConfigMap exists in the workflow's namespace with the configured key, or the DB row exists
- Fix controller RBAC so it can read the ConfigMap (`argoproj.io` sync ConfigMaps)
- Check controller logs for the wrapped underlying error to identify the exact source
- Restart/reconcile the workflow after fixing so initialization is retried
Example fix
// before: missing ConfigMap kubectl get configmap my-semaphore-cm -n argo # NotFound // after: create it kubectl create configmap my-semaphore-cm -n argo --from-literal=limit=3
Defensive patterns
Strategy: try-catch
Validate before calling
// ensure the semaphore ConfigMap exists and is readable before submitting kubectl get configmap <name> -n <wf-namespace> \ && kubectl auth can-i get configmap/<name> -n <wf-namespace> --as=system:serviceaccount:argo:argo-server
Try / catch
sem, err := manager.InitializeSemaphore(ctx, name)
if err != nil && strings.Contains(err.Error(), "failed to initialize semaphore") {
return fmt.Errorf("check ConfigMap/DB for semaphore %q: %w", name, err)
} Prevention
- Create semaphore ConfigMaps before submitting dependent workflows
- Grant the controller SA read access to sync ConfigMaps
- Keep semaphore names/keys consistent across namespaces and environments
When it happens
Trigger: initializeSemaphore is called during controller startup or when a semaphore is first needed; limitGetter.get (ConfigMap read or DB query) returns an error — missing ConfigMap, RBAC denial, DB failure.
Common situations: Semaphore ConfigMap deleted or in a different namespace; controller service account lacking get rights on the ConfigMap; database-backed semaphore with unreachable DB; typo in the semaphore name/key.
Related errors
- memoization configmap doesn't have %s label, refusing to use
- failed to unmarshal container args: %w
- failed to unmarshal template: %w
- if you have an item in your config map named 'config', you m
- issuer empty
AI-assisted analysis of argoproj/argo-workflows@35bff19146 (2026-09-03).
Data as JSON: /api/errors/79d5fa45d918857f.
Report an issue: GitHub.