gofiber/fiber · warning

shutdown: server is not running

Error message

shutdown: server is not running

What it means

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.

Solutions

  1. Only call Shutdown after Listen has returned or after ConfirmStartup confirms the server is up.
  2. Treat ErrNotRunning as expected in cleanup paths: ignore it with errors.Is(err, fiber.ErrNotRunning).
  3. If you drive shutdown from a goroutine, gate it on a started channel that Listen signals once app.server is non-nil.

Example fix

// before
if err := app.ShutdownWithContext(ctx); err != nil {
    return fmt.Errorf("shutdown: %w", err)
}
// after
if err := app.ShutdownWithContext(ctx); err != nil {
    if errors.Is(err, fiber.ErrNotRunning) {
        return nil // server was never started; nothing to do
    }
    return fmt.Errorf("shutdown: %w", err)
}
Defensive patterns

Strategy: validation

Validate before calling

// Only shut down if the server has actually started. Track startup with a
// channel that Listen signals once app.server is non-nil.
var started = make(chan struct{})

go func() {
    if err := app.Listen(":8080"); err != nil {
        log.Fatal(err)
    }
    close(started)
}()

select {
case <-started:
    _ = app.ShutdownWithContext(ctx)
case <-ctx.Done():
    // never started; nothing to shut down
}

Try / catch

if err := app.ShutdownWithContext(ctx); err != nil {
    if errors.Is(err, fiber.ErrNotRunning) {
        return nil // benign: server was never started
    }
    return fmt.Errorf("shutdown: %w", err)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of gofiber/fiber@a105acad6c (2026-08-11). Data as JSON: /api/errors/057e54f229139ff6. Report an issue: GitHub.

Appendix: source

Thrown at error.go:18

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")
	// ErrRouteNotRepresentable indicates a route whose path no relative URL can
	// name, so Route.URL, GetRouteURL and Redirect().Route cannot compose one.
	// A path starting with two or more slashes is such a route: the URL that
	// would reach it opens an authority instead.
	ErrRouteNotRepresentable = errors.New("router: route path cannot be expressed as a relative URL")
)

// Fiber redirection errors
var (
	ErrRedirectBackNoFallback = NewError(StatusInternalServerError, "Referer not found, you have to enter fallback URL for redirection.")
)

View on GitHub (pinned to a105acad6c)