thanos-io/thanos · warning
canceled
Error message
canceled
What it means
interrupt() waits for SIGINT/SIGTERM; if instead the cancel channel closes (meaning some other run-group actor failed or the group is shutting down), it returns errors.New("canceled"). This is Thanos's normal way to terminate the signal-waiting actor when shutdown is initiated elsewhere, and it propagates up to cause a clean exit.
Solutions
- Treat this as a secondary/shutdown error; scan the logs for the earlier root-cause error that closed the cancel channel.
- If it appears alone, check whether another component was stopped (systemd, k8s liveness kill, docker stop).
- No code fix needed if shutdown was intentional; fix the root failure otherwise.
Defensive patterns
Strategy: try-catch
Try / catch
// Treat 'canceled' as expected on shutdown
if err := g.Run(); err != nil {
if errors.Is(errors.Cause(err), context.Canceled) || err.Error() == "canceled" {
logger.Info("graceful shutdown")
return nil
}
return err
} Prevention
- Always correlate this message with an earlier root-cause error in logs
- Alert on the root cause, not on the 'canceled' shutdown message
- Use structured logging so the error chain stays greppable
When it happens
Trigger: Another run-group actor returns an error or the group is terminated, closing the cancel channel while interrupt() is still blocked waiting on signals; the select then takes the <-cancel branch and returns "canceled".
Common situations: A component (HTTP/gRPC server, store client) failed and triggered group shutdown; or the group's interrupt/ctx cancel fired during graceful shutdown. Often appears alongside the actual root-cause error in logs.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
AI-assisted analysis of thanos-io/thanos@35b8b99117 (2026-09-07).
Data as JSON: /api/errors/1ec31f23c12e4566.
Report an issue: GitHub.
Appendix: source
Thrown at cmd/thanos/main.go:183
}
if err := g.Run(); err != nil {
// Use %+v for github.com/pkg/errors error to print with stack.
level.Error(logger).Log("err", fmt.Sprintf("%+v", errors.Wrapf(err, "%s command failed", cmd)))
os.Exit(1)
}
level.Info(logger).Log("msg", "exiting")
}
func interrupt(logger log.Logger, cancel <-chan struct{}) error {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
select {
case s := <-c:
level.Info(logger).Log("msg", "caught signal. Exiting.", "signal", s)
return nil
case <-cancel:
return errors.New("canceled")
}
}
func reload(logger log.Logger, cancel <-chan struct{}, r chan<- struct{}) error {
c := make(chan os.Signal, 1)
signal.Notify(c, syscall.SIGHUP)
for {
select {
case s := <-c:
level.Info(logger).Log("msg", "caught signal. Reloading.", "signal", s)
select {
case r <- struct{}{}:
level.Info(logger).Log("msg", "reload dispatched.")
default:
}
case <-cancel:
return errors.New("canceled")
}View on GitHub (pinned to 35b8b99117)