{"record":{"id":"389fc1f984d13aca","repo":"jaegertracing/jaeger","slug":"error-shutting-down-cleaner-server-w","errorCode":null,"errorMessage":"error shutting down cleaner server: %w","messagePattern":"error shutting down cleaner server: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/jaeger/internal/integration/storagecleaner/extension.go","lineNumber":81,"sourceCode":"\t\tAddr:              \":\" + c.config.Port,\n\t\tHandler:           mux,\n\t\tReadHeaderTimeout: 3 * time.Second,\n\t}\n\tc.telset.Logger.Info(\"Starting storage cleaner server\", zap.String(\"addr\", c.server.Addr))\n\tgo func() {\n\t\tif err := c.server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {\n\t\t\terr = fmt.Errorf(\"error starting cleaner server: %w\", err)\n\t\t\tcomponentstatus.ReportStatus(host, componentstatus.NewFatalErrorEvent(err))\n\t\t}\n\t}()\n\n\treturn nil\n}\n\nfunc (c *storageCleaner) Shutdown(ctx context.Context) error {\n\tif c.server != nil {\n\t\tif err := c.server.Shutdown(ctx); err != nil {\n\t\t\treturn fmt.Errorf(\"error shutting down cleaner server: %w\", err)\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (*storageCleaner) Dependencies() []component.ID {\n\treturn []component.ID{jaegerstorage.ID}\n}\n","sourceCodeStart":63,"sourceCodeEnd":90,"githubUrl":"https://github.com/jaegertracing/jaeger/blob/806f4447841ecdb60519f408b004a599d515f437/cmd/jaeger/internal/integration/storagecleaner/extension.go#L63-L90","documentation":"During Shutdown the extension gracefully drains its internal HTTP server with c.server.Shutdown(ctx). If the server cannot stop within the context's deadline or returns another error, it is wrapped as 'error shutting down cleaner server' and propagated from Shutdown, failing the component shutdown.","triggerScenarios":"Shutdown() is called while the purge HTTP server still has active connections that do not finish before ctx is canceled, or the underlying listener returns an error during close.","commonSituations":"A purge request is in flight and the OTel shutdown timeout is shorter than the purge duration; using an already-canceled or very short shutdown context; stalled connections (keep-alive clients) keeping the drain alive.","solutions":["Increase the component shutdown timeout so in-flight purge requests can complete","Ensure clients stop issuing purge requests before shutting down the collector","Retry shutdown with a fresh context; if persistent, investigate stuck connections with netstat/ss"],"exampleFix":"// before\nctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)\n// after\nctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)","handlingStrategy":"try-catch","validationCode":"// ensure no long-running purge requests before shutdown\n// optionally poll the /purge endpoint's readiness and let in-flight calls finish","typeGuard":null,"tryCatchPattern":"if err := ext.Shutdown(ctx); err != nil {\n    if errors.Is(ctx.Err(), context.DeadlineExceeded) {\n        // retry with a longer deadline\n        ctx2, cancel := context.WithTimeout(context.Background(), 30*time.Second)\n        defer cancel()\n        err = ext.Shutdown(ctx2)\n    }\n}","preventionTips":["Give the collector a shutdown timeout longer than worst-case purge duration","Avoid issuing purge requests during shutdown windows","Monitor for stuck connections on the cleaner port"],"tags":["shutdown","http-server","timeout"],"backgroundTag":"graceful-shutdown-timeout","analyzedSha":"806f4447841ecdb60519f408b004a599d515f437","analyzedAt":"2026-09-01T02:39:22.140Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}