gofiber/fiber · error
failed to unmarshal response: %w
Error message
failed to unmarshal response: %w
What it means
Returned by maybeWriteCachedResponse (idempotency.go:75-76) when msgpack UnmarshalMsg fails on the bytes returned by Storage.Get. The cached payload is corrupted or was written by an incompatible schema version of this middleware.
Source
Thrown at middleware/idempotency/idempotency.go:76
// Snapshot the configured names so later mutation of the caller's slice
// cannot change an already-constructed handler. Matching uses
// utils.EqualFold, so no lowercased copies are needed and comparing
// against the canonical-case names fasthttp reports stays allocation-free.
keepResponseHeaders := slices.Clone(cfg.KeepResponseHeaders)
shouldKeepHeader := func(header string) bool {
return slices.ContainsFunc(keepResponseHeaders, func(keep string) bool {
return utils.EqualFold(header, keep)
})
}
maybeWriteCachedResponse := func(c fiber.Ctx, key string) (bool, error) {
if val, err := cfg.Storage.GetWithContext(c, key); err != nil {
return false, fmt.Errorf("failed to read response: %w", err)
} else if val != nil {
var res response
if _, err := res.UnmarshalMsg(val); err != nil {
return false, fmt.Errorf("failed to unmarshal response: %w", err)
}
_ = c.Status(res.StatusCode)
for header, vals := range res.Headers {
for _, val := range vals {
c.RequestCtx().Response.Header.Add(header, val)
}
}
if len(res.Body) != 0 {
if err := c.Send(res.Body); err != nil {
return true, err
}
}
_ = c.Locals(localsKeyIsFromCache, true)
View on GitHub (pinned to 9a4c7e57fe)
Solutions
- Namespace idempotency keys so they cannot collide with other Storage users (prefix the key in your KeyGenerator).
- After a schema-changing upgrade, flush the affected Storage keys or bump the key prefix.
- Investigate any non-idempotency code writing to the same Storage keyspace.
Example fix
// before — keys share namespace with other apps KeyHeader: "X-Idempotency-Key" // after — prefix keys so collisions are impossible Next: nil, // (wrap storage or use a prefixed storage adapter so all keys start with "idem:")
Defensive patterns
Strategy: validation
Validate before calling
// namespace keys to prevent collisions
KeyGenerator: func(c fiber.Ctx) string {
return "idem:" + c.Get("X-Idempotency-Key")
} Prevention
- Prefix all idempotency Storage keys so no other subsystem can collide.
- Flush Storage keys after upgrading the middleware across schema changes.
- Never let unrelated code write to the same Storage keyspace.
When it happens
Trigger: Storage holds bytes for the key that are not a msgpack-encoded response (manual write, key collision with another subsystem); an upgrade changed the response struct fields; partial writes from a crashed instance; storage backend bit-rot.
Common situations: Deploying a new version of the idempotency middleware whose response struct shape differs; two services sharing a Storage namespace and colliding on key prefixes; backup restore of stale data.
Related errors
- cache: failed to unmarshal key %q: %w
- cache: failed to marshal key %q: %w
- failed to read response: %w
- failed to write cached response at fastpath: %w
- failed to write cached response while locked: %w
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/3010c8ec51713671.json.
Report an issue: GitHub.