yudai/gotty · error

Server is shutting down

Error message

Server is shutting down

What it means

Not a thrown exception but the HTTP body of a 503 (StatusServiceUnavailable) response: in --once mode the single allowed connection has already been claimed via a CAS on the once counter, so every subsequent websocket request is refused with this plain-text message while the server winds down.

Source

Thrown at server/handlers.go:34

	"github.com/yudai/gotty/webtty"
)

func (server *Server) generateHandleWS(ctx context.Context, cancel context.CancelFunc, counter *counter) http.HandlerFunc {
	once := new(int64)

	go func() {
		select {
		case <-counter.timer().C:
			cancel()
		case <-ctx.Done():
		}
	}()

	return func(w http.ResponseWriter, r *http.Request) {
		if server.options.Once {
			success := atomic.CompareAndSwapInt64(once, 0, 1)
			if !success {
				http.Error(w, "Server is shutting down", http.StatusServiceUnavailable)
				return
			}
		}

		num := counter.add(1)
		closeReason := "unknown reason"

		defer func() {
			num := counter.done()
			log.Printf(
				"Connection closed by %s: %s, connections: %d/%d",
				closeReason, r.RemoteAddr, num, server.options.MaxConnection,
			)

			if server.options.Once {
				cancel()
			}
		}()

View on GitHub (pinned to a080c85cbc)

Solutions

  1. Expected behavior in once mode: have clients honor 503 and stop retrying
  2. Restart or supervise the server (systemd) to re-arm one-shot sessions
  3. Use a load balancer to drain traffic once the one-shot slot is taken
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at server/handlers.go:34 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of yudai/gotty@a080c85cbc (2026-09-02). Data as JSON: /api/errors/dad6a507a88d6d8f. Report an issue: GitHub.