-
-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
Bug Description
Panic when using fiber.Ctx as context.Context after upgrading v3 beta.4 β v3.0.0-rc.1
After migrating from v3 beta.4 (where we used c.Context()) to v3.0.0-rc.1 (where fiber.Ctx itself implements context.Context), our app randomly panics when fiber.Ctx is passed as a context.Context into code that continues running after the handler returns.
The crash typically appears after a handful of requests (e.g., 5β20), then intermittently every few requests.
Environment
- Fiber:
v3.0.0-rc.1 - fasthttp:
v1.65.0 - Go:
1.25.0(darwin/arm64) - OS: macOS
Actual Behavior
Intermittent panic (example):
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x100f7d764]
goroutine 66 [running]:
github.com/valyala/fasthttp.(*RequestCtx).UserValue(...)
.../github.com/valyala/fasthttp@v1.65.0/server.go:773
github.com/gofiber/fiber/v3.(*DefaultCtx).Value(0x100000000?, {0x1018c0320?, 0x1023b3d40?})
.../github.com/gofiber/fiber/v3@v3.0.0-rc.1/ctx.go:382 +0x24
context.value({0x101a656a0?, 0x14000246140?}, {0x1018c0320, 0x1023b3d40})
.../src/context/context.go:801 +0x230
context.(*cancelCtx).Value(0x1023b3d4e?, {0x1018c0320?, 0x1023b3d40?})
.../src/context/context.go:445 +0x6c
net.(*sysDialer).dialSingle(0x140000d2000, {0x101a656a0, 0x140001525a0}, {0x101a61aa8, 0x1400014a0c0})
.../src/net/dial.go:704 +0x5c
net.(*sysDialer).dialSerial(0x140000d2000, {0x101a656a0, 0x140001525a0}, {0x14000030470?, 0x1, 0x100c94130?})
.../src/net/dial.go:686 +0x194
net.(*sysDialer).dialParallel.func1({0x101a656a0?, 0x140001525a0?}, 0x1)
.../src/net/dial.go:606 +0x64
created by net.(*sysDialer).dialParallel in goroutine 35
.../src/net/dial.go:621 +0x1b4
Analysis / Likely Root Cause
- In
v3.0.0-rc.1,fiber.Ctximplementscontext.Contextand(*DefaultCtx).Valuedelegates tofasthttp.RequestCtx.UserValue. - After the handler returns,
fiber.Ctxgets reused, and the underlyingRequestCtxmay be cleared ornil. - Any later call to
ctx.Value(...)(e.g., in background goroutines or async client work) dereferences anilpointer β panic. - The intermittent nature suggests a race between handler completion and background work accessing
ctx.Value(...).
Regression Note
This behavior surfaced after the migration beta.4 β rc.1, when switching from c.Context() to using fiber.Ctx directly as context.Context. While this may be intended as a breaking change, the current behavior is surprising because it results in a panic instead of a safe no-op.
How to Reproduce
Steps to Reproduce (minimal)
package main
import (
"context"
"net/http"
"time"
"github.com/gofiber/fiber/v3"
)
func main() {
app := fiber.New()
app.Get("/", func(c fiber.Ctx) error {
// IMPORTANT: pass fiber.Ctx as context.Context
req, _ := http.NewRequest("GET", "http://example.com", nil)
req = req.WithContext(c)
client := &http.Client{Timeout: 5 * time.Second}
// Run in a goroutine so it may outlive the handler
go func() { _, _ = client.Do(req) }()
return c.SendString("ok")
})
_ = app.Listen(":8080")
}Reproduce by sending multiple requests quickly (e.g., for i in {1..50}; do curl -s http://localhost:8080 >/dev/null; done).
Expected Behavior
Expected Behavior
- Either using
fiber.Ctxascontext.Contextshould not panic even if referenced after the handler returns (at worst,Value/Done/Errreturn safe values),
or - Provide/document a way to obtain a safe, detached std
context.Context(a snapshot of user-values + cancellation) that can be passed outside the request lifetime.
Fiber Version
v3.0.0-rc.1
Code Snippet (optional)
Checklist:
- I agree to follow Fiber's Code of Conduct.
- I have checked for existing issues that describe my problem prior to opening this one.
- I understand that improperly formatted bug reports may be closed without explanation.