gofiber/fiber · error

cache: failed to get raw key %q from storage: %w

Error message

cache: failed to get raw key %q from storage: %w

What it means

Thrown at middleware/cache/manager.go:145 by manager.getRaw() when the configured fiber.Storage backend returns a non-nil error from GetWithContext on the raw-bytes read path (used for cached response bodies / ETag payloads rather than the msgp item). Identical in cause to error 140 but on the raw read API.

Source

Thrown at middleware/cache/manager.go:145

	}

	if value := m.memory.Get(key); value != nil {
		it, ok := value.(*item)
		if !ok {
			return nil, fmt.Errorf("cache: unexpected entry type %T for key %q", value, m.logKey(key))
		}
		return it, nil
	}

	return nil, errCacheMiss
}

// get raw data from storage or memory
func (m *manager) getRaw(ctx context.Context, key string) ([]byte, error) {
	if m.storage != nil {
		raw, err := m.storage.GetWithContext(ctx, key)
		if err != nil {
			return nil, fmt.Errorf("cache: failed to get raw key %q from storage: %w", m.logKey(key), err)
		}
		if raw == nil {
			return nil, errCacheMiss
		}
		return raw, nil
	}

	if value := m.memory.Get(key); value != nil {
		raw, ok := value.([]byte)
		if !ok {
			return nil, fmt.Errorf("cache: unexpected raw entry type %T for key %q", value, m.logKey(key))
		}
		return raw, nil
	}

	return nil, errCacheMiss
}

View on GitHub (pinned to 9a4c7e57fe)

Solutions

  1. Read the wrapped driver error to identify the root cause (connectivity, auth, timeout) and resolve it at the backend.
  2. Health-check the storage endpoint at startup and on deploys so a bad config fails fast instead of at request time.
  3. Tune the storage driver's timeout / pool to ride through brief outages.
  4. Add a fiber.ErrorHandler that logs the raw-storage failure and serves an uncached response so users aren't blocked.
  5. Ensure the per-request context has a deadline longer than the storage read timeout to avoid spurious context.DeadlineExceeded.

Example fix

// before
store := redis.New() // default 0 timeout

// after: explicit read timeout + boot-time connectivity check
store := redis.New(redis.Config{
    URL:       os.Getenv("REDIS_URL"),
    ReadTimeout: 2 * time.Second,
})
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()
if _, err := store.GetWithContext(ctx, "healthcheck"); err != nil && !errors.Is(err, storage.ErrNotFound) {
    log.Fatalf("cache storage unhealthy: %v", err)
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Boot-time connectivity probe for the raw read path.
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
if _, err := store.GetWithContext(ctx, "__raw_probe__"); err != nil {
    log.Fatalf("cache raw storage unhealthy: %v", err)
}

Try / catch

raw, err := m.storage.GetWithContext(ctx, key)
if err != nil {
    if errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
        return nil, errCacheMiss // client gave up; degrade
    }
    log.Printf("raw storage read failed: %v", err)
    return nil, err
}

Prevention

When it happens

Trigger: A cached route or internal helper calls getRaw while Storage is configured and the backend GET fails: connection lost, query error, or the request context is cancelled before the storage returns.

Common situations: Redis/DB backend down or flapping; ctx cancelled because the client disconnected; storage driver misconfigured (wrong URL, expired credentials); network partition.

Related errors


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