{"record":{"id":"057e54f229139ff6","repo":"gofiber/fiber","slug":"shutdown-server-is-not-running","errorCode":null,"errorMessage":"shutdown: server is not running","messagePattern":"shutdown: server is not running","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"error.go","lineNumber":18,"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.\")\n)\n","sourceCodeStart":1,"sourceCodeEnd":36,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/error.go#L1-L36","documentation":"ErrNotRunning is returned by App.ShutdownWithContext (app.go:1337) when app.server is nil, i.e. when a Shutdown variant is called before the server has been started by Listen or Listener. It is a benign precondition error: there is nothing to drain because no listener was ever bound.","triggerScenarios":"Calling app.Shutdown(), app.ShutdownWithTimeout(d), or app.ShutdownWithContext(ctx) before app.Listen(addr) (or Listener/ListenTLS/ListenMutualTLS) has been invoked. Also seen in test teardown when the test never started the server, and in graceful-shutdown signal handlers that fire before serve completes.","commonSituations":"Signal-handling shutdown wired up before the listen goroutine has assigned app.server; tests that construct an App for handler unit-tests and then call Shutdown in t.Cleanup; race between startup failure and the SIGTERM handler.","solutions":["Only call Shutdown after Listen has returned or after ConfirmStartup confirms the server is up.","Treat ErrNotRunning as expected in cleanup paths: ignore it with errors.Is(err, fiber.ErrNotRunning).","If you drive shutdown from a goroutine, gate it on a started channel that Listen signals once app.server is non-nil."],"exampleFix":"// before\nif err := app.ShutdownWithContext(ctx); err != nil {\n    return fmt.Errorf(\"shutdown: %w\", err)\n}\n// after\nif err := app.ShutdownWithContext(ctx); err != nil {\n    if errors.Is(err, fiber.ErrNotRunning) {\n        return nil // server was never started; nothing to do\n    }\n    return fmt.Errorf(\"shutdown: %w\", err)\n}","handlingStrategy":"validation","validationCode":"// Only shut down if the server has actually started. Track startup with a\n// channel that Listen signals once app.server is non-nil.\nvar started = make(chan struct{})\n\ngo func() {\n    if err := app.Listen(\":8080\"); err != nil {\n        log.Fatal(err)\n    }\n    close(started)\n}()\n\nselect {\ncase <-started:\n    _ = app.ShutdownWithContext(ctx)\ncase <-ctx.Done():\n    // never started; nothing to shut down\n}","typeGuard":null,"tryCatchPattern":"if err := app.ShutdownWithContext(ctx); err != nil {\n    if errors.Is(err, fiber.ErrNotRunning) {\n        return nil // benign: server was never started\n    }\n    return fmt.Errorf(\"shutdown: %w\", err)\n}","preventionTips":["Treat ErrNotRunning as expected in signal handlers and test cleanup.","Gate shutdown on a startup-confirmed signal so the SIGTERM handler cannot race the serve goroutine.","In tests, only call Shutdown when the test actually started the server."],"tags":["shutdown","lifecycle","sentinel","precondition"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}