{"record":{"id":"fef3dc7f62de047c","repo":"vitessio/vitess","slug":"received-signal-v","errorCode":null,"errorMessage":"received signal: %v","messagePattern":"received signal: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"go/vt/vtadmin/grpcserver/server.go","lineNumber":221,"sourceCode":"\n\tlmux := cmux.New(lis)\n\n\tif s.opts.CMuxReadTimeout > 0 {\n\t\tlmux.SetReadTimeout(s.opts.CMuxReadTimeout)\n\t}\n\n\tgrpcLis := lmux.MatchWithWriters(cmux.HTTP2MatchHeaderFieldSendSettings(\"content-type\", \"application/grpc\"))\n\tanyLis := lmux.Match(cmux.Any())\n\n\tshutdown := make(chan error, 16)\n\n\tsignals := make(chan os.Signal, 8)\n\tsignal.Notify(signals, syscall.SIGTERM, syscall.SIGQUIT)\n\n\t// listen for signals\n\tgo func() {\n\t\tsig := <-signals\n\t\terr := fmt.Errorf(\"received signal: %v\", sig)\n\t\tlog.Warn(fmt.Sprint(err))\n\t\tshutdown <- err\n\t}()\n\n\tif s.opts.MetricsEndpoint != \"\" {\n\t\tif !strings.HasPrefix(s.opts.MetricsEndpoint, \"/\") {\n\t\t\ts.opts.MetricsEndpoint = \"/\" + s.opts.MetricsEndpoint\n\t\t}\n\n\t\tgrpc_prometheus.Register(s.gRPCServer)\n\t\ts.router.Handle(s.opts.MetricsEndpoint, promhttp.Handler())\n\t}\n\n\t// Start the servers\n\tgo func() {\n\t\terr := s.gRPCServer.Serve(grpcLis)\n\t\terr = fmt.Errorf(\"grpc server stopped: %w\", err)\n\t\tlog.Warn(fmt.Sprint(err))","sourceCodeStart":203,"sourceCodeEnd":239,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtadmin/grpcserver/server.go#L203-L239","documentation":"grpcserver.Server installs a signal handler for SIGTERM/SIGQUIT; when one arrives it constructs an error \"received signal: %v\" and sends it to the shutdown channel, triggering graceful shutdown. This is not an unexpected failure — it is the server's deliberate mechanism to convert OS signals into a shutdown cause so in-flight work can be logged and drained.","triggerScenarios":"The process receives SIGTERM (systemd/k8s stop, docker stop) or SIGQUIT (manual kill -QUIT) while ListenAndServe is running; the goroutine at server.go:221 forwards it to shutdown.","commonSituations":"Kubernetes rolling deploys sending SIGTERM to pods; operators restarting vtadmin; CI teardown killing the process; seeing this in logs and mistaking an intentional stop for a crash.","solutions":["No fix needed if the shutdown was intentional — this is the graceful-shutdown path.","If unexpected, audit what sends SIGTERM/SIGQUIT (orchestrator, watchdogs, OOM-adjacent tooling).","Check shutdown handling after this error to confirm connections drained cleanly.","For k8s, tune terminationGracePeriodSeconds so shutdown completes in time."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if err := server.ListenAndServe(ctx); err != nil {\n  if strings.HasPrefix(err.Error(), \"received signal:\") {\n    log.Info(\"vtadmin stopped by signal; exiting cleanly\")\n    return nil\n  }\n  return err\n}","preventionTips":["Expect SIGTERM-driven shutdowns in orchestrators; treat this error as normal exit.","Ensure graceful shutdown completes within your orchestrator's grace period.","Don't send SIGQUIT casually — it's wired into shutdown here.","Log and inspect the signal value to identify who stopped the process."],"tags":["signals","shutdown","grpc","server-lifecycle"],"backgroundTag":"sigterm-shutdown","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}