gofiber/fiber · warning · ErrGracefulTimeout
shutdown: graceful timeout has been reached, exiting
Error message
shutdown: graceful timeout has been reached, exiting
What it means
ErrGracefulTimeout (error.go:16) is the sentinel returned by Fiber's shutdown path when the graceful shutdown window expires before all in-flight connections reach idle. It is the user-facing signal that ShutdownWithTimeout / ShutdownWithContext hit the deadline and the server is exiting, rather than waiting indefinitely. Callers typically branch on it to decide whether to log a warning or proceed with forced cleanup.
Source
Thrown at error.go:16
package fiber
import (
"encoding/json"
"errors"
"github.com/gofiber/schema"
)
// Wrap and return this for unreachable code if panicking is undesirable (i.e., in a handler).
// Unexported because users will hopefully never need to see it.
var errUnreachable = errors.New("fiber: unreachable code, please create an issue at github.com/gofiber/fiber")
// General errors
var (
ErrGracefulTimeout = errors.New("shutdown: graceful timeout has been reached, exiting")
// ErrNotRunning indicates that a Shutdown method was called when the server was not running.
ErrNotRunning = errors.New("shutdown: server is not running")
// ErrHandlerExited is returned by App.Test if a handler panics or calls runtime.Goexit().
ErrHandlerExited = errors.New("runtime.Goexit() called in handler or server panic")
// ErrNoViewEngineConfigured indicates that a helper requiring a view engine was invoked without one configured.
ErrNoViewEngineConfigured = errors.New("fiber: no view engine configured")
// ErrAutoCertWithCertFile indicates AutoCertManager cannot be used with CertFile/CertKeyFile.
ErrAutoCertWithCertFile = errors.New("tls: AutoCertManager cannot be combined with CertFile/CertKeyFile")
)
// Fiber redirection errors
var (
ErrRedirectBackNoFallback = NewError(StatusInternalServerError, "Referer not found, you have to enter fallback URL for redirection.")
)
// Range errors
var (
// ErrRangeMalformed is returned for a syntactically invalid Range header,View on GitHub (pinned to 9a4c7e57fe)
Solutions
- Increase the shutdown timeout so it exceeds your longest acceptable request duration.
- Set a non-zero ReadTimeout / IdleTimeout so keep-alive connections are reaped during shutdown.
- Ensure handlers respect the request context and abort on ctx.Done() instead of blocking indefinitely.
- Treat this error as non-fatal in your shutdown handler: log it and continue exiting, since the server is already stopping.
Example fix
// before
if err := app.ShutdownWithTimeout(1 * time.Second); err != nil {
log.Fatal(err)
}
// after
if err := app.ShutdownWithTimeout(30 * time.Second); err != nil {
if errors.Is(err, fiber.ErrGracefulTimeout) {
log.Printf("graceful shutdown timed out, forcing exit")
} else {
log.Printf("shutdown error: %v", err)
}
} Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure the shutdown timeout exceeds your slowest handler.
maxRequest := 30 * time.Second
if shutdownTimeout < maxRequest {
shutdownTimeout = maxRequest + 5*time.Second
} Try / catch
if err := app.ShutdownWithTimeout(timeout); err != nil {
if errors.Is(err, fiber.ErrGracefulTimeout) {
log.Printf("graceful timeout reached, forcing exit")
} else if !errors.Is(err, fiber.ErrNotRunning) {
log.Printf("shutdown error: %v", err)
}
} Prevention
- Set a non-zero ReadTimeout/IdleTimeout so keep-alive connections drain during shutdown.
- Make handlers respect ctx.Done() so they abort promptly on shutdown.
- Treat ErrGracefulTimeout as informational, not fatal, in signal handlers.
When it happens
Trigger: Calling app.ShutdownWithTimeout(d) or app.ShutdownWithContext(ctx) while long-lived or keep-alive connections are still open and the deadline (d / ctx deadline) elapses first. Slow streaming handlers or stuck WebSocket loops are the usual cause.
Common situations: Production SIGTERM handling where ReadTimeout is 0 (keep-alive connections never close), handlers blocking on downstream services, or a shutdown timeout that is shorter than the slowest acceptable request. Deploying behind a load balancer that drains connections slowly also surfaces it.
Related errors
- shutdown: server is not running
- runtime.Goexit() called in handler or server panic
- min constraint requires an argument
- max constraint requires an argument
- range constraint requires two arguments
AI-assisted analysis of gofiber/fiber@9a4c7e57fe (2026-08-04).
Data as JSON: /data/errors/295a3bcb29f14487.json.
Report an issue: GitHub.