The Early Data middleware adds TLS 1.3 “0-RTT” support to Fiber. When the client and server share a PSK, TLS 1.3 lets the client send data with the first flight and skip the initial round trip.
Enable Fiber’s TrustProxy option before using this middleware to avoid spoofed client headers. When TrustProxy is disabled (the default) or the remote address is not trusted by your proxy configuration, requests carrying the Early-Data header are rejected with 425 Too Early to prevent 0-RTT spoofing from direct clients.
Enabling early data in a reverse proxy (for example, ssl_early_data on; in nginx) makes requests replayable. Review the security implications:
By default, the middleware permits early data only for safe methods (GET, HEAD, OPTIONS, TRACE) and rejects other requests before your handler runs. Override this behavior with the AllowEarlyData option.
Signatures
func New(config ...Config) fiber.Handler
func IsEarly(c fiber.Ctx) bool
IsEarly returns true when a request used early data and the middleware allowed it to proceed.
Usage
import (
"github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/middleware/earlydata"
)
Basic Example
// Initialize default config
app.Use(earlydata.New())
// Or extend your config for customization
app.Use(earlydata.New(earlydata.Config{
Error: fiber.ErrTooEarly,
}))
Check if Request Used Early Data
app.Get("/", func(c fiber.Ctx) error {
if earlydata.IsEarly(c) {
// Request came via 0-RTT
return c.SendString("Early data was used!")
}
return c.SendString("Normal request")
})
Configuration
Next
func(fiber.Ctx) bool
default:"nil"
Skip this middleware when the function returns true.
Reports whether the request used early data.
Decides if an early-data request should be allowed.
Error
error
default:"fiber.ErrTooEarly"
Returned when an early-data request is rejected.
Default Config
var ConfigDefault = Config{
IsEarlyData: func(c fiber.Ctx) bool {
return c.Get(DefaultHeaderName) == DefaultHeaderTrueValue
},
AllowEarlyData: func(c fiber.Ctx) bool {
return fiber.IsMethodSafe(c.Method())
},
Error: fiber.ErrTooEarly,
}
Constants
const (
DefaultHeaderName = "Early-Data"
DefaultHeaderTrueValue = "1"
)
Common Use Cases
Allow Early Data for Specific Routes
app.Use(earlydata.New(earlydata.Config{
AllowEarlyData: func(c fiber.Ctx) bool {
// Only allow early data for read-only API endpoints
return strings.HasPrefix(c.Path(), "/api/read/") &&
fiber.IsMethodSafe(c.Method())
},
}))
Custom Early Data Detection
app.Use(earlydata.New(earlydata.Config{
IsEarlyData: func(c fiber.Ctx) bool {
// Check custom header from your proxy
return c.Get("X-Early-Data") == "true"
},
}))
Strict Security - Reject All Early Data
app.Use(earlydata.New(earlydata.Config{
AllowEarlyData: func(c fiber.Ctx) bool {
return false // Reject all early data requests
},
}))
Logging Early Data Requests
app.Use(earlydata.New())
app.Use(func(c fiber.Ctx) error {
if earlydata.IsEarly(c) {
log.Printf("Early data request: %s %s", c.Method(), c.Path())
}
return c.Next()
})