{"record":{"id":"295a3bcb29f14487","repo":"gofiber/fiber","slug":"shutdown-graceful-timeout-has-been-reached-exiti","errorCode":null,"errorMessage":"shutdown: graceful timeout has been reached, exiting","messagePattern":"shutdown: graceful timeout has been reached, exiting","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"error.go","lineNumber":16,"sourceCode":"package fiber\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\n\t\"github.com/gofiber/schema\"\n)\n\n// Wrap and return this for unreachable code if panicking is undesirable (i.e., in a handler).\n// Unexported because users will hopefully never need to see it.\nvar errUnreachable = errors.New(\"fiber: unreachable code, please create an issue at github.com/gofiber/fiber\")\n\n// General errors\nvar (\n\tErrGracefulTimeout = errors.New(\"shutdown: graceful timeout has been reached, exiting\")\n\t// ErrNotRunning indicates that a Shutdown method was called when the server was not running.\n\tErrNotRunning = errors.New(\"shutdown: server is not running\")\n\t// ErrHandlerExited is returned by App.Test if a handler panics or calls runtime.Goexit().\n\tErrHandlerExited = errors.New(\"runtime.Goexit() called in handler or server panic\")\n\t// ErrNoViewEngineConfigured indicates that a helper requiring a view engine was invoked without one configured.\n\tErrNoViewEngineConfigured = errors.New(\"fiber: no view engine configured\")\n\t// ErrAutoCertWithCertFile indicates AutoCertManager cannot be used with CertFile/CertKeyFile.\n\tErrAutoCertWithCertFile = errors.New(\"tls: AutoCertManager cannot be combined with CertFile/CertKeyFile\")\n\t// ErrRouteNotRepresentable indicates a route whose path no relative URL can\n\t// name, so Route.URL, GetRouteURL and Redirect().Route cannot compose one.\n\t// A path starting with two or more slashes is such a route: the URL that\n\t// would reach it opens an authority instead.\n\tErrRouteNotRepresentable = errors.New(\"router: route path cannot be expressed as a relative URL\")\n)\n\n// Fiber redirection errors\nvar (\n\tErrRedirectBackNoFallback = NewError(StatusInternalServerError, \"Referer not found, you have to enter fallback URL for redirection.\")","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/error.go#L1-L34","documentation":"ErrGracefulTimeout is a public sentinel declared at error.go:16 that signals a graceful shutdown exceeded its deadline. In this fiber/v3 checkout it has no internal callers: the shutdown path in listen.go drives app.ShutdownWithContext and surfaces context.DeadlineExceeded instead. The sentinel exists as part of the public API so that callers comparing against it (or future revisions that return it) get a stable value to match with errors.Is.","triggerScenarios":"The error would be returned by a Shutdown variant once graceful draining of in-flight connections exceeds the supplied timeout. In the current revision, callers see context.DeadlineExceeded from the context passed to ShutdownWithContext; matching ErrGracefulTimeout returns false unless the application wraps and returns it itself.","commonSituations":"Long-running handlers (websockets, slow uploads, streaming responses) that keep connections alive past the shutdown deadline; test harnesses that assert on a specific graceful-timeout error and find a context error instead; version upgrades where the returned sentinel changes.","solutions":["If you depend on this exact value, match with errors.Is(err, fiber.ErrGracefulTimeout) so your code keeps working if a future revision returns it.","To stop the timeout firing, raise the shutdown deadline passed to ShutdownWithTimeout, or accelerate handler drain (close idle keep-alive connections, signal websocket peers to close).","If you need to surface this sentinel from your own shutdown wrapper, wrap and return it explicitly when ctx.Err() != nil during ShutdownWithContext."],"exampleFix":"// before\nif err := app.ShutdownWithTimeout(5 * time.Second); err != nil {\n    log.Printf(\"shutdown failed: %v\", err)\n}\n// after\nif err := app.ShutdownWithTimeout(30 * time.Second); err != nil {\n    if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, fiber.ErrGracefulTimeout) {\n        log.Printf(\"graceful shutdown timed out; forcing close\")\n    } else {\n        log.Printf(\"shutdown failed: %v\", err)\n    }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"// isGracefulTimeout reports whether err represents a graceful-shutdown\n// timeout. It matches both the public sentinel and context.DeadlineExceeded\n// (the value the current revision actually returns from ShutdownWithContext).\nfunc isGracefulTimeout(err error) bool {\n    return errors.Is(err, fiber.ErrGracefulTimeout) ||\n        errors.Is(err, context.DeadlineExceeded)\n}","tryCatchPattern":"if err := app.ShutdownWithTimeout(d); err != nil {\n    if isGracefulTimeout(err) {\n        log.Printf(\"graceful shutdown timed out; forcing close\")\n    } else {\n        return err\n    }\n}","preventionTips":["Match with errors.Is so the code keeps working when the returned sentinel changes.","Right-size the shutdown deadline for the slowest handler (websockets, uploads).","Signal long-lived connections to close before initiating shutdown."],"tags":["shutdown","lifecycle","sentinel","network"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}