V3 Beta Feedback: Help Us Fix Issues Before RC Release
V3 Beta Feedback: What Needs Fixing Before RC?
Hi Fiber community,
We're gearing up to ship V3's release candidate (RC) by mid-July 2025, but we need your help to make sure it’s rock-solid. V3’s been in beta too long, and we suspect some bugs or usability issues are holding us back. This issue is a poll to figure out what’s broken or not working right in the V3 beta (v3.0.0-beta.4).
Please share specific issues you’ve hit—bugs, performance problems, confusing APIs, or anything else. Use this template:
Issue Description: Title / Link to Github Issue
- What’s broken or not right?
- Steps to reproduce (code snippets help!)
- Expected vs. actual behavior
- Environment (Go version, OS, etc.)
Our Plan to Ship V3
We’ve let too many niche features delay V3, so we’re locking it down to focus on stability. Here’s what we’re doing and why:
- Feature Freeze: No new features, just bug fixes and core improvements to ensure a stable RC.
- Timeline: RC by mid-July 2025, stable release by mid-August 2025, to get V3 into production ASAP.
- Community Feedback: A poll will help us prioritize fixes based on what you’re seeing in the wild.
-
Stricter PRs: All pull requests must have documentation including migration guide in
whats_new.md, and solid tests to avoid new issues. -
Docs Update: We’re refreshing
whats_new.mdand other docs to reflect changes and make V3 easier to adopt.
Poll: Comment with a 👍 on the issues below that you think are critical to fix before RC. Or add your own.
We’ll review your feedback by May 30, 2025, prioritize the top issues, and share a fix plan. Thanks for helping us make V3 awesome!
Make fiber.Ctx implement context.Context https://github.com/gofiber/fiber/issues/3344
- What’s broken or not right?: Having too many different types of contexts is confusing - especially for new people transitioning from other languages to Go. If it's going to be simplified, now is the time to do it.
- Steps to reproduce: If the user wants to pass custom values around from middleware to middleware etc, they can directly store it in fasthttp's request's user values OR even better, we make fiber.Ctx implement context.Context and allow them to store it in there.
- Expected vs. actual behavior: N/A
- Environment (Go version, OS, etc.): N/A
Allow removing registered route #3098
- What’s broken or not right?: Following the addition of RebuildTree method https://github.com/gofiber/fiber/issues/2769, which enabled dynamic request handling, @rebaz94 proposed enhancing this functionality by allowing the removal of registered routes.
- Steps to reproduce: N/A
- Expected vs. actual behavior: N/A
- Environment (Go version, OS, etc.): N/A
It's great to see the Fiber team committed to preparing for the v3 release!
In fact, my team started developing an important and complex ERP system last year using v3-beta2. After more than a year of development, it was delivered to the client last month. It's a shame Fiber v3 is still in beta.
Based on our project requirements, we wrapped some of Fiber's applications ourselves, and it worked very well.
I really like Fiber, and I believe its future development will surpass Gin (which benefited from an earlier release and faster versioning).
Currently, we haven't found any major bugs, but we do have two minor issues where we'd appreciate some syntactic sugar:
Error Handling with fiber.NewError()
Many times, we'd like to use fiber.NewError() to return more error information, similar to this:
app.Get("/", func(c fiber.Ctx) error {
return fiber.NewError(309094, "some error message", "another reason", "doc/url or something...", "...")
})
Of course, we'll catch and handle errors in the ErrorHandler.
Since fiber.NewError doesn't currently support more variadic parameters, we had to extend it with a custom pkg.NewError() to achieve similar functionality.
Passing context.Context Values
In Fiber v3-beta2, it's inconvenient that we can't pass standard context.Context values within fiber.Ctx. This is because we eventually pass fiber.Ctx to the model layer and need to retrieve context.Value values. I've noticed that v3-beta4 seems to have a similar solution, but I haven't tested it yet.
Fiber is excellent, but its iteration speed is too slow. This is detrimental to Fiber gaining market share among popular Go frameworks.
@pwtitle I have a working branch for your request with fiber.NewError(), will report back thus week. The change should be doable.
Bug List
version v3.0.0-beta.5
limiter
error message
runtime error: invalid memory address or nil pointer dereference
I assume the problem might be related to DefaultConfig#Storage
example code
https://github.com/gozeon/zxc/blob/f877559da995e819f2a22fffb42f573e7e82df22/pkg/router/api_router.go#L12
csrf
error message
Forbidden
The issue I encountered while referring to the csrf#server-side-forms documentation.
example code
https://github.com/gozeon/zxc/blob/f877559da995e819f2a22fffb42f573e7e82df22/pkg/router/http_router.go#L15
redirect(flash message)
https://docs.gofiber.io/next/api/redirect#flash-message
When should messages be cleared? parseAndClearFlashMessages was not used.
example code
https://github.com/gozeon/zxc/blob/f877559da995e819f2a22fffb42f573e7e82df22/controller/page_controller/edit.go
Developer Experience Enhancement: Better Error Context for Common Issues
Based on experience building production Fiber applications, I'd like to propose improved error messaging for common developer pain points that often cause confusion during development:
Issue Description
Enhanced Error Messages for Body Limit and Configuration Issues
- What's broken: When body limit is exceeded, developers get generic 413 errors without context about default limits
- Expected behavior: Clear error messages indicating the specific limit and how to configure it
- Environment: All versions, particularly impacts new developers migrating from Express/other frameworks
Root Cause Analysis
The issue stems from Fiber's performance-first approach where default limits (4MB body limit) prioritize efficiency but can confuse developers unfamiliar with these defaults. Similar issues occur with:
-
Body limit exceeded:
413 Request Entity Too Largewith no context - Parsing failures: Cryptic validation errors without field context
- Development vs Production: Different behavior between environments
Proposed Solutions
1. Development Mode Error Enhancement
// Development-mode enhanced error responses
if app.Config().IsDevelopment {
return c.Status(413).JSON(fiber.Map{
"error": "Request Entity Too Large",
"message": "Request body exceeds the configured limit",
"details": fiber.Map{
"current_limit": "4MB",
"received_size": formatBytes(contentLength),
"solution": "Increase BodyLimit in fiber.Config{BodyLimit: <desired_size>}",
"docs": "https://docs.gofiber.io/api/fiber#config",
},
})
}
2. Configuration Validation Warnings
// Startup warnings for common misconfigurations
if app.Config().BodyLimit == defaultBodyLimit {
app.logger.Warn("Using default BodyLimit (4MB). Consider setting explicitly for production")
}
3. Enhanced Error Middleware
// Optional enhanced error middleware for development
func EnhancedErrorHandler() fiber.ErrorHandler {
return func(c *fiber.Ctx, err error) error {
if strings.Contains(err.Error(), "request body too large") {
return c.Status(413).JSON(DeveloperFriendlyError{
Type: "BODY_LIMIT_EXCEEDED",
// ... enhanced context
})
}
return fiber.DefaultErrorHandler(c, err)
}
}
Benefits for V3
- Faster onboarding: New developers understand issues immediately
- Better DX: Clear actionable error messages
- Production ready: Optional development-only enhancements
- Framework adoption: Easier migration from Express/other frameworks
Backward Compatibility
All enhancements would be:
- ✅ Opt-in via development mode flag
- ✅ Zero performance impact in production
- ✅ Fully backward compatible
- ✅ Configurable/disableable
This addresses the discoverability issues mentioned in the strategy documents while maintaining Fiber's performance-first philosophy.
Would the maintainers be interested in a PR implementing these developer experience improvements for V3?
I'm encountering a somewhat confusing issue in Fiber Beta V3.
First, I configured cookie encryption and CSRF middleware like this:
// Provide a minimal configuration
app.Use(encryptcookie.New(encryptcookie.Config{
Key: viper.GetString("APP_KEY"),
Next: func(c fiber.Ctx) bool {
return strings.HasPrefix(c.Path(), "/api/")
},
}))
app.Use(csrf.New(csrf.Config{
KeyLookup: "form:csrf_token",
CookieName: "csrf_token",
CookieSameSite: "Strict",
// Skip CSRF for routes starting with /api/
Next: func(c fiber.Ctx) bool {
return strings.HasPrefix(c.Path(), "/api/")
},
}))
However, the issue I encountered is related to displaying the csrf_token value in an HTML form like this:
<input type="hidden" name="csrf_token" value="{{ csrf_token }}" />
The token value is retrieved using:
csrf.TokenFromContext(c)
But of course, this value is not encrypted. The site still works fine and passes CSRF validation, but this makes the cookie encryption seem meaningless — I couldn't find any function that returns the encrypted CSRF token for rendering into the HTML view.
Sorry if the explanation is unclear or I’ve misunderstood something. Thank you for taking the time to look into this. I truly appreciate your support.
@quocduongpy Try changing the middlewares order:
- csrf
- encryptcookie
@gaby I’ve tried, but it didn’t work correctly:
The CSRF validator failed to verify the token. The csrf_token is still not encrypted when passed down to the HTML view.
I'm encountering a somewhat confusing issue in Fiber Beta V3.
First, I configured cookie encryption and CSRF middleware like this:
// Provide a minimal configuration app.Use(encryptcookie.New(encryptcookie.Config{ Key: viper.GetString("APP_KEY"), Next: func(c fiber.Ctx) bool { return strings.HasPrefix(c.Path(), "/api/") }, })) app.Use(csrf.New(csrf.Config{ KeyLookup: "form:csrf_token", CookieName: "csrf_token", CookieSameSite: "Strict", // Skip CSRF for routes starting with /api/ Next: func(c fiber.Ctx) bool { return strings.HasPrefix(c.Path(), "/api/") }, }))However, the issue I encountered is related to displaying the csrf_token value in an HTML form like this:
<input type="hidden" name="csrf_token" value="{{ csrf_token }}" />The token value is retrieved using:
csrf.TokenFromContext(c)But of course, this value is not encrypted. The site still works fine and passes CSRF validation, but this makes the cookie encryption seem meaningless — I couldn't find any function that returns the encrypted CSRF token for rendering into the HTML view.
Sorry if the explanation is unclear or I’ve misunderstood something. Thank you for taking the time to look into this. I truly appreciate your support.
TL;DR
You don’t need to encrypt CSRF tokens.
A token is a security mechanism — it proves something about the request, like that it came from a valid user or session — but that doesn’t mean it needs to be encrypted. Tokens like CSRF tokens or session IDs are not secrets; they’re just unpredictable, random values that are hard to guess. Their strength comes from their randomness and how they’re verified on the server, not from being hidden.
It’s perfectly fine for these tokens to be visible to the client (e.g., in a cookie or in the HTML) because the browser needs access to them to include them in requests. Encrypting them adds unnecessary complexity and can break middleware that expects to read them in plain text.
If you’re storing something truly sensitive — like a password, a signing key, or a JWT containing confidential claims — then encrypting it might make sense (though you should first reconsider why you’re sending secrets to the client at all). For typical session or CSRF tokens, however, encryption isn’t necessary. Instead, focus on using strong, random tokens combined with secure cookie flags like HttpOnly, Secure, and SameSite to keep them safe.
@SeyramWood which fiber version do you use? can you share a minimal example
@ReneWerner87
I think there’s an issue when converting a Fiber handler to a net/http handler, specifically for SSE. The request gets stuck and does not work as expected, because the adapter waits for the handler to return before streaming data.
This is really important for example, I currently can't use MCP because it uses a net/http handler, and using the adapter does not work properly.
Does v3 provide a fix or a better way to handle streaming/long-lived handlers in this scenario?
@rebaz94 SSE support is work in progress, it's a bit more complicated for adaptor. We will discuss internally and report back
@gaby SSE already works, but prioritizing improvements to the adapter to make it work seamlessly with standard net/http handlers would be great.
too many options for context. what’s the point of keeping fiber.Ctx, request.Ctx and Graceful Shutdown context? it should be either one or the other. for a long time we used v3 beta and now we have to remove all c.Context() calls, which did not really add any value anyway. fiber’s context is not really a proper context.Context, so it would be simpler to just drop those methods like Done, Deadline, etc that are no-op indeed. and keep only one Context function which can be attached at the creating of Fiber server as the only Context implementator. thanks!
@arlanram We are adding Context() back, which is missing from rc1.
The fiber.Ctx doesn't implement everything and it also re-used after the handler returns.
Fixes were done in #3720
Hi. I've caught a problem. I cannot extract path like "/readings/:id" in original form in the middleware. It's always like "/readings/123". I use fiber v3.0.0-rc.1 I've tried ctx.Path(), ctx.Route().Path, ctx.OriginalURL()
@arlanram rc2 is out https://github.com/gofiber/fiber/releases/tag/v3.0.0-rc.2
v3.0.0-rc2 bug #3848
app.Use breaks when using NewWithCustomCtx
@ReneWerner87