{"record":{"id":"fc8b47dcf49af0dc","repo":"gofiber/fiber","slug":"cache-failed-to-marshal-key-q-w","errorCode":null,"errorMessage":"cache: failed to marshal key %q: %w","messagePattern":"cache: failed to marshal key %q: %w","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"middleware/cache/manager.go","lineNumber":170,"sourceCode":"\n\tif value := m.memory.Get(key); value != nil {\n\t\traw, ok := value.([]byte)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"cache: unexpected raw entry type %T for key %q\", value, m.logKey(key))\n\t\t}\n\t\treturn raw, nil\n\t}\n\n\treturn nil, errCacheMiss\n}\n\n// set data to storage or memory\nfunc (m *manager) set(ctx context.Context, key string, it *item, exp time.Duration) error {\n\tif m.storage != nil {\n\t\traw, err := it.MarshalMsg(nil)\n\t\tif err != nil {\n\t\t\tm.release(it)\n\t\t\treturn fmt.Errorf(\"cache: failed to marshal key %q: %w\", m.logKey(key), err)\n\t\t}\n\t\tif err := m.storage.SetWithContext(ctx, key, raw, exp); err != nil {\n\t\t\tm.release(it)\n\t\t\treturn fmt.Errorf(\"cache: failed to store key %q: %w\", m.logKey(key), err)\n\t\t}\n\t\tm.release(it)\n\t\treturn nil\n\t}\n\n\tm.memory.Set(key, it, exp)\n\treturn nil\n}\n\n// set data to storage or memory\nfunc (m *manager) setRaw(ctx context.Context, key string, raw []byte, exp time.Duration) error {\n\tif m.storage != nil {\n\t\tif err := m.storage.SetWithContext(ctx, key, raw, exp); err != nil {\n\t\t\treturn fmt.Errorf(\"cache: failed to store raw key %q: %w\", m.logKey(key), err)","sourceCodeStart":152,"sourceCodeEnd":188,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/middleware/cache/manager.go#L152-L188","documentation":"Returned by manager.set when it.MarshalMsg fails while serializing a cache item before storing it externally. MarshalMsg can fail because the item struct declares msgp field limits (e.g. value limit=16384, headers limit=1024) that reject oversized fields.","triggerScenarios":"Caching a response whose header value exceeds the 16384-byte limit, with more than 1024 headers, a content-type over 256 bytes, cache-control over 2048 bytes, etc.; any single cachedHeader field breaching its declared msgp field limit during encode.","commonSituations":"Handlers that echo very large header values (long Set-Cookie, oversized Link/Content-Security-Policy, base64-encoded blobs in headers); responses with hundreds of headers; upstream proxies injecting massive header blocks. Memory-Storage mode never marshals, so this is external-Storage only.","solutions":["Identify which header/field is oversized by inspecting the response being cached (the wrapped msgp error often names the offending field).","Exclude the offending header from caching via the cache middleware's header-ignore configuration if its value is not cache-relevant.","Do not cache responses known to carry oversized header payloads (set a cache-control: no-store or skip these routes).","If the limit genuinely must be higher, it requires regenerating the msgp code with raised limits — not a runtime config."],"exampleFix":"// before: caching a route that emits an oversized header\napp.Get(\"/blob\", emitHugeHeaderHandler, cache.New())\n\n// after: opt that route out of caching\napp.Get(\"/blob\", emitHugeHeaderHandler) // no cache.New()","handlingStrategy":"validation","validationCode":"// Validate the response is cache-safe (no oversized headers) BEFORE storing.\nconst maxHeaderValue = 16384 // matches cachedHeader.value msgp limit\n\nfunc headerWithinLimits(h *fasthttp.ResponseHeader) error {\n    var offender string\n    h.VisitAll(func(k, v []byte) {\n        if len(v) > maxHeaderValue {\n            offender = string(k)\n        }\n    })\n    if offender != \"\" {\n        return fmt.Errorf(\"header %s exceeds %d-byte cache limit\", offender, maxHeaderValue)\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := headerWithinLimits(respHdr); err != nil {\n    log.Warn(\"skipping cache for oversized response:\", err)\n    // do not cache this response\n} else {\n    _ = manager.set(ctx, key, it, exp)\n}","preventionTips":["Do not cache routes known to emit oversized header values.","Exclude volatile/huge headers (Link, Content-Security-Policy, Set-Cookie) from caching via the middleware's ignore list.","After changing the item struct or its msgp limits, regenerate manager_msgp.go."],"tags":["cache","serialization","msgp","field-limit","headers","go","fiber"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}