Skip to content

Don't fail container list when size lookup fails - #53921

Merged
vvoland merged 1 commit into
moby:masterfrom
drakeo338:claude/53920-fix
Oct 14, 2026
Merged

vvoland merged 1 commit into
moby:masterfrom
drakeo338:claude/53920-fix

Conversation

@drakeo338

@drakeo338 drakeo338 commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

With size=true, an error from GetContainerLayerSize for a single container (for example the containerd snapshotter failing on a container whose snapshot is gone) failed the whole container list, so one broken container made docker ps -s and docker system df unusable. The list now logs the error at debug level, reports that container's sizes as -1 (as the graphdriver image service does for SizeRw when Size() fails), and keeps the container in the result. TestContainerList_SizeError covers it: it fails before the change and passes after.

AI disclosure: written with Claude Code (AI-assisted, mostly AI-drafted); I reviewed the change and ran the daemon tests.

Release notes (optional)

Fix `docker ps -s` and container listing with sizes failing entirely when the size of one container cannot be computed.

A picture of a cute animal (not mandatory but encouraged)

Skipped.

@github-actions github-actions Bot added the area/daemon Core Engine label Oct 12, 2026
Comment thread daemon/list_test.go Outdated

ok := setupContainerWithName(t, "ok", d)
bad := setupContainerWithName(t, "bad", d)
bad.Created = ok.Created.Add(time.Millisecond)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this isn't needed

Suggested change
bad.Created = ok.Created.Add(time.Millisecond)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed in 31abdb8, along with the ok variable it left unused.

@vvoland vvoland added this to the 29.9.1 milestone Oct 12, 2026
@vvoland vvoland added the kind/bugfix PR's that fix bugs label Oct 12, 2026
Comment thread daemon/list.go Outdated
Comment on lines +168 to +173
// Don't fail the whole listing because the size of a
// single container can't be determined.
log.G(ctx).WithFields(log.Fields{
"error": err,
"containerID": newC.ID,
}).Warn("failed to get container layer size")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like in other places we made this a Debug;

moby/daemon/prune.go

Lines 71 to 77 in 553420b

cSize, _, err := daemon.imageService.GetContainerLayerSize(ctx, c.ID)
if err != nil {
// Debug log only, the size is only for informational purposes anyway
log.G(ctx).WithFields(log.Fields{
"error": err,
"container": c.ID,
}).Debug("failed to get layer size for container")

That said, I'm wondering if we should also special-case "not found" errors if they are potentially expected. In that case we could even consider setting the sizes to 0. Could there also be a situation where only one (SizeRw or SizeRootFs) cannot be found? (writable layer already gone, but rootFS not?) 🤔

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's some handling already for not found in the function we're calling, including some logging (so we could end up with multiple logs for the same error);

snapshotter := i.client.SnapshotService(ctr.Driver)
rwLayerUsage, err := snapshotter.Usage(ctx, containerID)
if err != nil {
if cerrdefs.IsNotFound(err) {
return 0, 0, errdefs.NotFound(fmt.Errorf("rw layer snapshot not found for container %s", containerID))
}
return 0, 0, errdefs.System(errors.Wrapf(err, "snapshotter.Usage failed for %s", containerID))
}
unpackedUsage, err := calculateSnapshotParentUsage(ctx, snapshotter, containerID)
if err != nil {
if cerrdefs.IsNotFound(err) {
log.G(ctx).WithField("ctr", containerID).Warn("parent of container snapshot no longer present")
} else {
log.G(ctx).WithError(err).WithField("ctr", containerID).Warn("unexpected error when calculating usage of the parent snapshots")
}
}
log.G(ctx).WithFields(log.Fields{
"rwLayerUsage": rwLayerUsage.Size,
"unpacked": unpackedUsage.Size,
}).Debug("GetContainerLayerSize")
// TODO(thaJeztah): include content-store size for the image (similar to "GET /images/json")
return rwLayerUsage.Size, rwLayerUsage.Size + unpackedUsage.Size, nil

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to Debug in 31abdb8. No double log: a missing rw snapshot comes back from service.go as 0, 0 plus NotFound without logging; the parent case it logs returns no error (SizeRootFs just under-counts). SizeRootFs is rw + parents, so if rw fails neither is available. Graphdriver returns 0, 0 for a missing layer, and system df sums SizeRw, so -1 skews it; happy to map NotFound to 0 if you prefer.

@vvoland

vvoland commented Oct 12, 2026

Copy link
Copy Markdown
Contributor

@drakeo338 can you please squash the commits?

When listing containers with size=true, an error from
GetContainerLayerSize for a single container (for example the
containerd snapshotter failing to compute usage for a container whose
snapshot is gone) was returned from the worker and made the whole
request fail, so one broken container made 'docker ps -s' and
'docker system df' unusable.

Log the error at debug level, as prune does for the same error, report
the sizes of that container as -1, which is what the graphdriver image
service already does when it cannot compute the size, and keep the
container in the result.

Signed-off-by: drakeo338 <[email protected]>
@drakeo338

Copy link
Copy Markdown
Contributor Author

Squashed into one commit, 9f89432, with the same tree as before.

@vvoland vvoland left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, LGTM!

@vvoland
vvoland merged commit cdfbf7d into moby:master Oct 14, 2026
235 of 237 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

3 participants