hashicorp/nomad · error
error decoding stats data: no reader body
Error message
error decoding stats data: no reader body
What it means
collectDockerStats calls Docker's stats API and then decodes the HTTP response body. If the returned statsReader has a nil Body, decoding is impossible, so the driver returns this error instead of panicking. It indicates the Docker API response was malformed or the client returned a response without content.
Source
Thrown at drivers/docker/stats.go:146
}
// collectDockerStats performs the stats collection from the Docker API. It is
// split into its own function for the purpose of aiding testing.
func (h *taskHandle) collectDockerStats(ctx context.Context) (*containerapi.StatsResponse, error) {
var stats *containerapi.StatsResponse
statsReader, err := h.dockerClient.ContainerStats(ctx, h.containerID, mclient.ContainerStatsOptions{
IncludePreviousSample: true,
})
if err != nil && err != io.EOF {
return nil, fmt.Errorf("failed to collect stats: %w", err)
}
// Ensure the body is not nil to avoid potential panics. The statsReader
// itself cannot be nil, so there is no need to check this.
if statsReader.Body == nil {
return nil, errors.New("error decoding stats data: no reader body")
}
err = json.NewDecoder(statsReader.Body).Decode(&stats)
_ = statsReader.Body.Close()
if err != nil && err != io.EOF {
return nil, fmt.Errorf("failed to decode Docker response: %w", err)
}
if stats == nil {
return nil, errors.New("error decoding stats data: stats were nil")
}
return stats, nil
}
View on GitHub (pinned to 482b49bf1a)
Solutions
- Check Docker daemon health and version; restart/upgrade the daemon if responses are malformed
- Retry the stats collection — the error is usually transient
- Verify container is still running at stats time; guard against races by checking task state
- Inspect Nomad client logs for repeated failures; if persistent, report to Nomad with Docker version
Defensive patterns
Strategy: retry
Validate before calling
// before stats: confirm container is running
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
if _, err := cli.ContainerInspect(ctx, containerID); err != nil { return err } Type guard
func hasBody(r *http.Response) bool { return r != nil && r.Body != nil } Try / catch
stats, err := collectDockerStats(ctx, cli, containerID)
if err != nil {
if strings.Contains(err.Error(), "no reader body") {
// transient: retry with backoff
return retry(3, 500*time.Millisecond, func() error { _, err := collectDockerStats(ctx, cli, containerID); return err })
}
return err
} Prevention
- Keep the Docker daemon upgraded and healthy
- Treat stats collection failures as transient and add retries
- Check container liveness before requesting stats
When it happens
Trigger: Docker daemon returning an http.Response whose Body is nil when the driver calls ContainerStats during collectStats for a running task.
Common situations: Docker daemon instability or an unexpected API response during `nomad stats` / stats collection; Docker client edge cases on older daemon versions; races where the container is removed while stats are being collected.
Related errors
- error decoding stats data: stats were nil
- DriverStatsNotImplemented
- running container as ContainerAdmin is unsafe; change the co
- does not match registry specification
- hostname is not currently supported on driver %s
AI-assisted analysis of hashicorp/nomad@482b49bf1a (2026-09-04).
Data as JSON: /api/errors/1f9f3a18b30338fc.
Report an issue: GitHub.