gofiber/fiber · error

cache: failed to restore heap index for key %q: %w

Error message

cache: failed to restore heap index for key %q: %w

What it means

Companion to the previous error, also inside refreshHeapIndex: after successfully re-reading the entry, manager.set failed while writing back the updated heapidx. The storage backend rejected the write, so the heap/index inconsistency could not be repaired. The wrapped error carries the storage driver's failure reason.

Source

Thrown at middleware/cache/cache.go:196

		_, size := heap.remove(heapIdx)
		storedBytes -= size
	}

	refreshHeapIndex := func(ctx context.Context, candidate evictionCandidate) error {
		entry, err := manager.get(ctx, candidate.key)
		if err != nil {
			if errors.Is(err, errCacheMiss) {
				return nil
			}
			return fmt.Errorf("cache: failed to reload key %q after eviction failure: %w", maskKey(candidate.key), err)
		}

		entry.heapidx = candidate.heapIdx

		remainingTTL := max(secondsToTime(entry.exp).Sub(cfg.now()), 0)

		if err := manager.set(ctx, candidate.key, entry, remainingTTL); err != nil {
			return fmt.Errorf("cache: failed to restore heap index for key %q: %w", maskKey(candidate.key), err)
		}

		return nil
	}

	// Return new handler
	return func(c fiber.Ctx) error {
		hasAuthorization := len(c.Request().Header.Peek(fiber.HeaderAuthorization)) > 0
		reqCacheControl := c.Request().Header.Peek(fiber.HeaderCacheControl)
		reqDirectives := parseRequestCacheControl(reqCacheControl)
		if !reqDirectives.noCache {
			reqPragma := utils.UnsafeString(c.Request().Header.Peek(fiber.HeaderPragma))
			if hasDirective(reqPragma, noCache) {
				reqDirectives.noCache = true
			}
		}

		// Refrain from caching

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Verify the storage backend accepts writes and has capacity (disk space, cluster health, WLM quotas).
  2. Increase the storage driver's write/timeout settings to tolerate the load.
  3. Reduce eviction pressure by increasing MaxBytes or lowering cacheable body sizes.
  4. If persistent, drain and reseed the cache (clear storage + restart) to remove any half-written entries.

Example fix

// before: storage write fails on rollback
storage := sqlite.New(...) // read-only mount

// after: writable storage with healthy capacity
storage := sqlite.New(sqlite.Config{
  Path: "/var/lib/app/cache.db",
  // ensure dir is writable and disk has free space
})
Defensive patterns

Strategy: try-catch

Validate before calling

func pingStorage(s fiber.Storage) error {
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()
    if err := s.Set(ctx, "__ping__", []byte("1"), 5*time.Second); err != nil {
        return fmt.Errorf("storage write check: %w", err)
    }
    return s.Delete(ctx, "__ping__")
}

Type guard

null

Try / catch

app.Use(func(c fiber.Ctx) error {
    err := c.Next()
    if err != nil && strings.Contains(err.Error(), "failed to restore heap index") {
        log.Warnf("cache write rollback failed: %v", err)
        return nil // degrade gracefully
    }
    return err
})

Prevention

When it happens

Trigger: Same eviction-rollback path as error 129, but manager.get succeeded and manager.set failed — e.g. storage is read-OK but write-blocked (disk full, read-replica, write-quorum lost). Forcible by injecting a set failure in the storage mock during eviction recovery.

Common situations: Redis cluster in a failover window (reads from replica, writes fail); SQLite storage on a full disk; storage connection read-timeout configured but write-timeout too small; replica-only storage accidentally wired into cache.

Related errors


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