gofiber/fiber · error
limiter: unexpected entry type %T for key
Error message
limiter: unexpected entry type %T for key %q
What it means
On the in-memory storage path (no fiber.Storage configured), the manager stores *item values in memory.Storage. A type assertion to *item failing means something else was Put under the same key. Under normal use this is unreachable because only the manager writes to its memory store.
Solutions
- Confirm nothing else writes to the same memory.Storage instance; the manager creates its own via memory.New() when storage is nil, so this only happens if you injected a shared one.
- If testing, use a fresh memory.Storage per limiter instance or let the limiter allocate its own (pass nil storage).
- Search the codebase for any external Set on the storage backing the limiter.
- Reset the in-memory store (restart the process) to clear the mistyped entry.
Example fix
// before: shared memory store pollutes limiter keys
shared := memory.New()
shared.Set("limiter:1.2.3.4", "not-an-item", time.Minute)
limiter.New(limiter.Config{Storage: shared}) // nil external storage but shared memory is not configurable here
// after: let the limiter own its memory store
limiter.New(limiter.Config{}) Defensive patterns
Strategy: validation
Validate before calling
// Ensure the limiter owns its memory store — pass nil storage so it allocates privately.
limiter.New(limiter.Config{}) // Storage left nil Prevention
- Never inject a shared memory.Storage into the limiter.
- In tests, instantiate a fresh limiter per case rather than reusing one.
- Audit external code that may hold a reference to the limiter's internal storage.
When it happens
Trigger: External code obtained a reference to the same memory.Storage instance and Set a non-*item value under a key that collides with the limiter's key prefix; an in-process test fixture populated the memory store with the wrong type; a second limiter manager sharing the same memory.Storage with a different value type.
Common situations: Test setup that reuses a shared memory.Storage across middleware; a fork or plugin that writes into the limiter's storage layer directly; a code regression that switched the stored type without migrating the in-memory store.
Related errors
- cache: unexpected entry type %T for key
- cache: unexpected raw entry type %T for key
- csrf: unexpected value type %T in storage
- limiter: failed to marshal key
- limiter: failed to get key
AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11).
Data as JSON: /api/errors/1fba0994cb9f1f60.
Report an issue: GitHub.
Appendix: source
Thrown at middleware/limiter/manager.go:90
if raw != nil {
it := m.acquire()
if _, err := it.UnmarshalMsg(raw); err != nil {
m.release(it)
return nil, fmt.Errorf("limiter: failed to unmarshal key %q: %w", m.logKey(key), err)
}
return it, nil
}
return m.acquire(), nil
}
value := m.memory.Get(key)
if value == nil {
return m.acquire(), nil
}
it, ok := value.(*item)
if !ok {
return nil, fmt.Errorf("limiter: unexpected entry type %T for key %q", value, m.logKey(key))
}
return it, nil
}
// set data to storage or memory
func (m *manager) set(ctx context.Context, key string, it *item, exp time.Duration) error {
if m.storage != nil {
raw, err := it.MarshalMsg(nil)
if err != nil {
m.release(it)
return fmt.Errorf("limiter: failed to marshal key %q: %w", m.logKey(key), err)
}
if err := m.storage.SetWithContext(ctx, key, raw, exp); err != nil {
m.release(it)
return fmt.Errorf("limiter: failed to store key %q: %w", m.logKey(key), err)
}
m.release(it)View on GitHub (pinned to a105acad6c)