gofiber/fiber · info

cache: no cached body for key %q: %w

Error message

cache: no cached body for key %q: %w

What it means

Thrown by cacheBodyFetchError() at middleware/cache/utils.go:19 when the wrapped error is exactly errCacheMiss - i.e. there is no cached body for the requested key. This is NOT a fault: it is the sentinel used to distinguish 'cache miss for body' from a genuine storage failure. It signals a cold/expired/evicted entry rather than a backend problem.

Source

Thrown at middleware/cache/utils.go:19

package cache

import (
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"fmt"
	"math"
	"sync"
	"time"

	"github.com/gofiber/fiber/v3"
	"github.com/gofiber/utils/v2"
	"github.com/valyala/fasthttp"
)

func cacheBodyFetchError(mask func(string) string, key string, err error) error {
	if errors.Is(err, errCacheMiss) {
		return fmt.Errorf("cache: no cached body for key %q: %w", mask(key), err)
	}
	return err
}

func cachedResponseAge(e *item, now uint64) uint64 {
	clampedDate := clampDateSeconds(e.date, now)

	resident := uint64(0)
	if e.exp != 0 {
		if e.exp <= now {
			resident = e.ttl + (now - e.exp)
		} else {
			resident = e.ttl - (e.exp - now)
		}
	}

	dateAge := uint64(0)
	if clampedDate != 0 && now > clampedDate {

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Treat this error as a soft miss, not an error: fetch from the origin and repopulate the cache.
  2. If misses are frequent, raise the cache TTL or increase storage capacity to reduce eviction.
  3. Warm the cache after deploys for hot keys to avoid cold-start misses.
  4. Confirm the key you are fetching was actually written (same CacheModifier / prefix as the write path).

Example fix

// before: treating the miss as an error
raw, err := m.getRaw(ctx, key)
if err != nil { return err }

// after: distinguish miss from real failure
raw, err := m.getRaw(ctx, key)
if errors.Is(err, errCacheMiss) {
    // cold cache - regenerate the body and store it
    raw = computeBody()
    _ = m.setRaw(ctx, key, raw, ttl)
} else if err != nil {
    return err
}
Defensive patterns

Strategy: fallback

Validate before calling

// Before fetching the body, accept that a miss is the common case.
// No pre-check is possible; treat errCacheMiss as a signal to repopulate.

Type guard

// Distinguish a soft miss from a hard storage failure.
func isCacheMiss(err error) bool {
    return errors.Is(err, errCacheMiss)
}

Try / catch

raw, err := m.getRaw(ctx, key)
if errors.Is(err, errCacheMiss) {
    // cold cache - regenerate, store, and return
    raw = computeBody()
    _ = m.setRaw(ctx, key, raw, ttl)
} else if err != nil {
    return err // genuine storage failure, not a miss
}

Prevention

When it happens

Trigger: A body-fetch helper is invoked for a key that was never cached, was evicted by the storage backend's LRU/TTL, or expired between the metadata hit and the body fetch.

Common situations: First request after a deploy (cold cache); entry TTL elapsed; Redis evicted the key under memory pressure; cache namespace changed so old keys no longer resolve.

Related errors


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