{"record":{"id":"608ab1575fc14dd0","repo":"gofiber/fiber","slug":"limiter-failed-to-unmarshal-key-q-w","errorCode":null,"errorMessage":"limiter: failed to unmarshal key %q: %w","messagePattern":"limiter: failed to unmarshal key %q: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"middleware/limiter/manager.go","lineNumber":76,"sourceCode":"func (m *manager) release(e *item) {\n\te.prevHits = 0\n\te.currHits = 0\n\te.exp = 0\n\tm.pool.Put(e)\n}\n\n// get data from storage or memory\nfunc (m *manager) get(ctx context.Context, key string) (*item, error) {\n\tif m.storage != nil {\n\t\traw, err := m.storage.GetWithContext(ctx, key)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"limiter: failed to get key %q from storage: %w\", m.logKey(key), err)\n\t\t}\n\t\tif raw != nil {\n\t\t\tit := m.acquire()\n\t\t\tif _, err := it.UnmarshalMsg(raw); err != nil {\n\t\t\t\tm.release(it)\n\t\t\t\treturn nil, fmt.Errorf(\"limiter: failed to unmarshal key %q: %w\", m.logKey(key), err)\n\t\t\t}\n\t\t\treturn it, nil\n\t\t}\n\t\treturn m.acquire(), nil\n\t}\n\n\tvalue := m.memory.Get(key)\n\tif value == nil {\n\t\treturn m.acquire(), nil\n\t}\n\n\tit, ok := value.(*item)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"limiter: unexpected entry type %T for key %q\", value, m.logKey(key))\n\t}\n\n\treturn it, nil\n}","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/limiter/manager.go#L58-L94","documentation":"After a successful storage.GetWithContext, the raw bytes are handed to item.UnmarshalMsg (msgp-generated). If the bytes are not a valid msgpack-encoded item, this error fires. The acquired *item is released back to the pool before returning, so the leak is bounded to the bytes themselves.","triggerScenarios":"Stored value for the limiter key was written by a different schema version (struct field reordered/renamed after msgp regeneration without clearing storage), the key namespace is shared with another fiber.Storage consumer that wrote arbitrary bytes, manual storage inspection/repopulation with wrong format, or storage corruption (truncated Redis value after a crash).","commonSituations":"Deploying a new fiber version where the internal `item` struct's msgp shape changed without flushing Redis; co-locating limiter keys in the same Redis DB as session keys with a colliding prefix; a Redis RDB/AOF restore from a backup made by a different app build.","solutions":["Flush the affected limiter keys (or the whole storage namespace) so stale, differently-encoded values are cleared: redis-cli KEYS 'limiter:*' | xargs redis-cli DEL.","Re-run go generate for the limiter package (msgp) and confirm manager_msgp.go is committed and matches the current item struct.","Use a distinct key prefix per app/build so a new schema version cannot read an old version's values.","If the corruption is from a shared namespace, set a unique StorageKeyPrefix in limiter.Config.","Roll back to the previous build or migrate storage atomically with the code change."],"exampleFix":"// before: shared prefix causes collision\nlimiter.New(limiter.Config{Storage: redisStore})\n\n// after: namespace per build, flush on deploy\nlimiter.New(limiter.Config{Storage: redisStore, StorageKeyPrefix: \"v2:limiter:\"})","handlingStrategy":"validation","validationCode":"// On deploy, verify no stale values collide with the new schema.\n// (infra step) redis-cli --scan --pattern 'limiter:*' | head; flush if schema changed.","typeGuard":null,"tryCatchPattern":"// Treat unmarshal failures as a poisoned key: delete and continue.\nif errors.Is(err, msgp.ErrShortBytes) { // or match the wrapped prefix\n  _ = storage.Del(key)\n}","preventionTips":["Version the limiter key prefix per build (StorageKeyPrefix in limiter.Config) so schema changes cannot read old values.","Re-run go generate ./middleware/limiter whenever the item struct changes.","Never share the limiter's Redis key namespace with other middleware.","Flush the limiter namespace on schema-affecting deploys."],"tags":["limiter","storage","msgpack","serialization","schema"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}