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
- Treat this error as a soft miss, not an error: fetch from the origin and repopulate the cache.
- If misses are frequent, raise the cache TTL or increase storage capacity to reduce eviction.
- Warm the cache after deploys for hot keys to avoid cold-start misses.
- 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
- Treat errCacheMiss as expected, not as an error.
- Warm hot keys after deploys to reduce cold-start misses.
- Size storage/TTL to your working set to keep misses low.
- Ensure the write and read paths use the same CacheModifier/prefix.
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
- cache: failed to get key %q from storage: %w
- cache: failed to unmarshal key %q: %w
- cache: unexpected entry type %T for key %q
- cache: failed to get raw key %q from storage: %w
- cache: unexpected raw entry type %T for key %q
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/ad96a526728d67c5.json.
Report an issue: GitHub.