gofiber/fiber · error
failed to write cached response while locked
Error message
failed to write cached response while locked: %w
What it means
Wraps an error from maybeWriteCachedResponse when re-checking the cache after acquiring the lock (double-checked locking pattern). Same underlying causes as errors 168/169 (storage read or unmarshal failure), but observed on the locked path — meaning another request may have just written or be writing the entry.
Solutions
- Address the storage/marshalling root cause (errors 168/169).
- If a concurrent writer is producing bad blobs, gate writes behind the same schema version.
- Investigate lock-holder interactions — ensure Unlock is always called (the deferred Unlock logs but does not propagate).
- Add tracing on the locked re-check path to correlate with concurrent writers.
Defensive patterns
Strategy: retry
Prevention
- Keep storage healthy across both fastpath and locked re-check.
- Ensure concurrent writers share the same response schema.
- Confirm Unlock always fires (deferred) to avoid lock leaks.
When it happens
Trigger: After cfg.Lock.Lock succeeds, the second maybeWriteCachedResponse call returns an error. Common when the storage briefly failed on the fastpath (error 170) and is still failing under the lock, or when a concurrent writer produced an unparseable blob that this holder then reads.
Common situations: Storage outage that spans both lookups, a race where a concurrent process wrote a schema-incompatible blob, or a storage backend under heavy load returning partial/corrupt reads.
Related errors
- failed to write cached response at fastpath
- failed to read response
- failed to save response
- cache: failed to delete cached response for key
- cache: failed to delete expired key
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/677869483f33b176.
Report an issue: GitHub.
Appendix: source
Thrown at middleware/idempotency/idempotency.go:136
// First-pass: if the idempotency key is in the storage, get and return the response
if ok, err := maybeWriteCachedResponse(c, key); err != nil {
return fmt.Errorf("failed to write cached response at fastpath: %w", err)
} else if ok {
return nil
}
if err := cfg.Lock.Lock(key); err != nil {
return fmt.Errorf("failed to lock: %w", err)
}
defer func() {
if err := cfg.Lock.Unlock(key); err != nil {
log.Errorf("[IDEMPOTENCY] failed to unlock key %q: %v", maskKey(key), err)
}
}()
// Lock acquired. If the idempotency key now is in the storage, get and return the response
if ok, err := maybeWriteCachedResponse(c, key); err != nil {
return fmt.Errorf("failed to write cached response while locked: %w", err)
} else if ok {
return nil
}
// Execute the request handler
if err := c.Next(); err != nil {
// If the request handler returned an error, return it and skip idempotency
return err
}
// Construct response
res := &response{
StatusCode: c.Response().StatusCode(),
Body: c.Response().Body(),
}
{
headers := make(map[string][]string)
if err := c.Bind().RespHeader(headers); err != nil {View on GitHub (pinned to a105acad6c)