{"record":{"id":"4cd8695031d8442f","repo":"docker/cli","slug":"timeout-waiting-for-stats","errorCode":null,"errorMessage":"timeout waiting for stats","messagePattern":"timeout waiting for stats","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cli/command/container/stats_helpers.go","lineNumber":154,"sourceCode":"\t\t\t\t\tNetworkRx:        netRx,\n\t\t\t\t\tNetworkTx:        netTx,\n\t\t\t\t\tBlockRead:        float64(blkRead),\n\t\t\t\t\tBlockWrite:       float64(blkWrite),\n\t\t\t\t\tPidsCurrent:      v.PidsStats.Current,\n\t\t\t\t})\n\t\t\t}\n\t\t\tu <- nil\n\t\t\tif !streamStats {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t}()\n\tfor {\n\t\tselect {\n\t\tcase <-time.After(2 * time.Second):\n\t\t\t// zero out the values if we have not received an update within\n\t\t\t// the specified duration.\n\t\t\ts.SetErrorAndReset(errors.New(\"timeout waiting for stats\"))\n\t\t\t// if this is the first stat you get, release WaitGroup\n\t\t\tif !getFirst {\n\t\t\t\tgetFirst = true\n\t\t\t\twaitFirst.Done()\n\t\t\t}\n\t\tcase err := <-u:\n\t\t\ts.SetError(err)\n\t\t\tif errors.Is(err, io.EOF) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif err != nil {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// if this is the first stat you get, release WaitGroup\n\t\t\tif !getFirst {\n\t\t\t\tgetFirst = true\n\t\t\t\twaitFirst.Done()\n\t\t\t}","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/docker/cli/blob/4f84911bfe8811e9b028e4b1fee8e7510be79387/cli/command/container/stats_helpers.go#L136-L172","documentation":"Set on a stats entry by the stats collector when no stats update is received from the daemon within 2 seconds (time.After(2*time.Second) in the select loop at stats_helpers.go:151). It indicates the streaming stats response stalled; the entry is marked with an error and reset. Common with very busy daemons, network hiccups, or containers that just stopped.","triggerScenarios":"Running `docker stats` (streaming) against a daemon that stops sending updates for >2s — e.g. high daemon load, slow remote socket (TCP/SSH), the container exiting mid-stream, or a proxy/load-balancer buffering the stream.","commonSituations":"Remote Docker hosts over slow/unstable TCP or SSH tunnels. Daemon under heavy CPU/memory pressure. Transient container exits during stats collection. TLS/VPN overhead inflating latency.","solutions":["Retry the stats command; transient stalls often clear.","Check daemon health and load (`docker info`, host CPU/mem); reduce load or restart the daemon if saturated.","For remote daemons, verify network latency/bandwidth and avoid buffering proxies between client and daemon.","Use `docker stats --no-stream` for a one-shot read that does not depend on a continuous stream."],"exampleFix":"// before\ndocker stats   # stalls >2s over a remote TCP socket\n\n// after\ndocker stats --no-stream","handlingStrategy":"retry","validationCode":"// For one-shot reads, request non-streaming stats to avoid the 2s stall window.\noptions.NoStream = true","typeGuard":null,"tryCatchPattern":"// Retry streaming stats a few times; fall back to --no-stream on repeated stalls.\nconst maxRetries = 3\nvar err error\nfor i := 0; i < maxRetries; i++ {\n    err = runStats(ctx, cli, options)\n    if err == nil {\n        break\n    }\n    if i == maxRetries-1 {\n        options.NoStream = true // fall back to one-shot\n        err = runStats(ctx, cli, options)\n    }\n}","preventionTips":["Use --no-stream for single snapshots to avoid the streaming timeout window.","Monitor daemon load; high load is a common cause of stalled stats streams.","For remote daemons, prefer low-latency, non-buffering connections (avoid HTTP proxies on the path)."],"tags":["stats","timeout","streaming","network","container"],"backgroundTag":null,"analyzedSha":"4f84911bfe8811e9b028e4b1fee8e7510be79387","analyzedAt":"2026-08-07T12:15:29.814Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}