kopia/kopia · warning
unable to acquire semaphore
Error message
unable to acquire semaphore
What it means
Thrown in the gRPC session server when s.sem.Acquire(ctx, 1) fails while enforcing the limit on concurrently handled requests. Acquire only fails when the provided context is cancelled or its deadline expires while waiting for a slot, meaning the request was abandoned before a worker became available.
Solutions
- Retry the request; this often means the client gave up while waiting.
- Increase the server's concurrency limit if handlers are habitually saturated.
- Investigate slow/stuck handlers blocking semaphore slots.
- Align client timeout settings with realistic server queue wait times.
Example fix
// before: default low concurrency kopia server start --max-concurrency=4 // after kopia server start --max-concurrency=32
Defensive patterns
Strategy: retry
Validate before calling
// client-side: use a deadline long enough to cover queue wait ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel()
Try / catch
err := client.Connect(ctx)
if err != nil && strings.Contains(err.Error(), "unable to acquire semaphore") {
// server saturated or client timed out waiting; back off and retry
return retryWithBackoff(ctx, Connect)
} Prevention
- Raise server concurrency limits to match client load
- Use generous client deadlines for bursty workloads
- Monitor server saturation and slow handlers
- Apply client-side backoff instead of hammering a saturated server
When it happens
Trigger: Client request arrives while the concurrency semaphore is full and the client's context is cancelled or times out before a slot frees up.
Common situations: Many concurrent kopia client operations saturating the server; client-side timeout shorter than the queue wait; server wedged on slow handlers so the queue never drains.
Understand the failure class
Background: Request timed out: what client-side request timeouts mean across libraries (Request timed out, TIMED_OUT, APITimeoutError) — this error's family across 39 libraries.
Related errors
AI-assisted analysis of kopia/kopia@82495e54b5 (2026-09-07).
Data as JSON: /api/errors/ec2e6468471dba04.
Report an issue: GitHub.
Appendix: source
Thrown at internal/server/grpc_session.go:145
for req, err := srv.Recv(); err == nil; req, err = srv.Recv() {
// propagate any error from the goroutines
select {
case err := <-lastErr:
userLog(ctx).Errorf("error handling session request: %v", err)
contentlog.Log1(ctx, log,
"error handling session request",
logparam.Error("error", err))
return err
default:
}
// enforce limit on concurrent handling
if err := s.sem.Acquire(ctx, 1); err != nil {
return errors.Wrap(err, "unable to acquire semaphore")
}
go func() {
defer s.sem.Release(1)
s.handleSessionRequest(ctx, dw, authz, usernameAtHostname, req, func(resp *grpcapi.SessionResponse) {
if err := s.send(srv, req.GetRequestId(), resp); err != nil {
select {
case lastErr <- err:
default:
}
}
})
}()
}
return nil
})View on GitHub (pinned to 82495e54b5)