{"record":{"id":"2163300aab282ab0","repo":"ipfs/kubo","slug":"daemon-is-shutting-down-started-s-ago","errorCode":null,"errorMessage":"daemon is shutting down (started %s ago)","messagePattern":"daemon is shutting down \\(started (.+?) ago\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/commands/diag.go","lineNumber":56,"sourceCode":"\t\t\"healthy\":   diagHealthyCmd,\n\t},\n}\n\n// diagHealthyCmd is a container-healthcheck probe. It fails when shutdown\n// has been initiated (even if the RPC API still answers) or when the DAG\n// pipeline cannot resolve a built-in CID.\nvar diagHealthyCmd = &cmds.Command{\n\tHelptext: cmds.HelpText{\n\t\tTagline: \"Report whether the daemon is operational.\",\n\t\tShortDescription: `\nExits 0 if the daemon is running and can resolve the well-known empty\nUnixFS directory. Exits non-zero if shutdown has started or the DAG\npipeline is broken. Intended for container healthchecks.\n`,\n\t},\n\tRun: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {\n\t\tif t := shutdown.StartedAt(); !t.IsZero() {\n\t\t\treturn fmt.Errorf(\"daemon is shutting down (started %s ago)\", time.Since(t).Round(time.Second))\n\t\t}\n\t\tapi, err := cmdenv.GetApi(env, req)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tprobeCID, err := cid.Decode(diagHealthyProbeCIDStr)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"invalid probe CID: %w\", err)\n\t\t}\n\t\tif _, _, err := api.ResolvePath(req.Context, path.FromCid(probeCID)); err != nil {\n\t\t\treturn fmt.Errorf(\"probe resolve: %w\", err)\n\t\t}\n\t\tif _, err := api.Dag().Get(req.Context, probeCID); err != nil {\n\t\t\treturn fmt.Errorf(\"probe fetch: %w\", err)\n\t\t}\n\t\treturn cmds.EmitOnce(res, \"ok\")\n\t},\n}","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/ipfs/kubo/blob/329838acdfafae224582930457efe80aa217afc0/core/commands/diag.go#L38-L74","documentation":"The `ipfs diag healthy` command fails fast when the daemon's shutdown sequence has already started: shutdown.StartedAt() is non-zero, so the command reports how long ago shutdown began and exits non-zero. This makes the command usable as a container healthcheck — a non-zero exit tells the orchestrator the node is going away.","triggerScenarios":"Calling `ipfs diag healthy` (locally or via RPC) after `ipfs shutdown` or SIGTERM initiated graceful shutdown.","commonSituations":"Kubernetes/Docker healthcheck probes hitting a node that is mid-shutdown; scripts racing a daemon restart.","solutions":["Wait for the daemon to restart and retry the healthcheck","Check `ipfs shutdown`/process lifecycle before probing","Adjust healthcheck retry/grace periods to tolerate shutdown windows"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// before probing, check liveness\nif t := shutdown.StartedAt(); !t.IsZero() { /* skip probe, node is shutting down */ }","typeGuard":null,"tryCatchPattern":"out, err := runCmd(\"ipfs diag healthy\")\nif err != nil && strings.Contains(err.Error(), \"daemon is shutting down\") { time.Sleep(gracePeriod); retry() }","preventionTips":["Configure healthchecks with retry counts and grace periods","Treat non-zero `ipfs diag healthy` exit as 'unhealthy, shutting down' in orchestrators"],"tags":["daemon","shutdown","healthcheck","cli"],"backgroundTag":"daemon-shutting-down","analyzedSha":"329838acdfafae224582930457efe80aa217afc0","analyzedAt":"2026-09-03T18:30:52.135Z","contentChangedAt":"2026-09-03T18:30:52.135Z","schemaVersion":2},"datasetVersion":"2026-09-11T00:17:11.886Z"}