gofiber/fiber · error

limiter: unexpected entry type %T for key %q

Error message

limiter: unexpected entry type %T for key %q

What it means

Returned by the in-memory path of manager.get when the value stored under the key in the in-memory store is not an *item. The code does it, ok := value.(*item); this type assertion fails when memory.Get yields something that is not the expected limiter item type.

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 9a4c7e57fe)

Solutions

  1. Ensure each limiter instance uses its own memory.Storage rather than sharing one across middlewares/packages.
  2. Check that no custom code writes into the limiter's memory store.
  3. If sharing storage is intentional, isolate by key namespace so types never collide.
Defensive patterns

Strategy: validation

Validate before calling

// Ensure each limiter uses a private in-memory store; do not share
// memory.Storage across middlewares.
func newIsolatedLimiter() fiber.Handler {
    // Omit Storage in Config to get a fresh internal memory store per call
    // to limiter.New.
    return limiter.New()
}

Try / catch

// Treat an internal type-assertion failure as a 500 and log it loudly,
// since it signals store misuse rather than a client error.
if strings.Contains(err.Error(), "unexpected entry type") {
    log.Error().Err(err).Msg("limiter memory store type collision")
    return c.Status(500).SendString("internal error")
}

Prevention

When it happens

Trigger: Limiter is running with the default in-memory storage (no fiber.Storage configured) and memory.Get returns a non-nil value whose dynamic type is not *item. In normal operation only *item values are stored, so this indicates the memory.Storage is being shared/misused across components that write a different type under the same key.

Common situations: Two middleware instances or another package sharing the same memory.Storage and writing a different value type to the same key; a fork or custom patch that stores a different struct; race/corruption in a shared in-memory store.

Related errors


AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04). Data as JSON: /data/errors/1fba0994cb9f1f60.json. Report an issue: GitHub.