{"record":{"id":"44d6c85ede7ffc2a","repo":"containerd/containerd","slug":"failed-to-get-container-spec-w-44d6c8","errorCode":null,"errorMessage":"failed to get container spec: %w","messagePattern":"failed to get container spec: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/cri/server/container_update_resources.go","lineNumber":96,"sourceCode":"func (c *criService) updateContainerResources(ctx context.Context,\n\tcntr containerstore.Container,\n\tr *runtime.UpdateContainerResourcesRequest,\n\tstatus containerstore.Status) (newStatus containerstore.Status, retErr error) {\n\n\tnewStatus = status\n\tid := cntr.ID\n\t// Do not update the container when there is a removal in progress.\n\tif status.Removing {\n\t\treturn newStatus, fmt.Errorf(\"container %q is in removing state\", id)\n\t}\n\n\t// Update container spec. If the container is not started yet, updating\n\t// spec makes sure that the resource limits are correct when start;\n\t// if the container is already started, updating spec is still required,\n\t// the spec will become our source of truth for resource limits.\n\toldSpec, err := cntr.Container.Spec(ctx)\n\tif err != nil {\n\t\treturn newStatus, fmt.Errorf(\"failed to get container spec: %w\", err)\n\t}\n\tnewSpec, err := updateOCIResource(ctx, oldSpec, r, c.config)\n\tif err != nil {\n\t\treturn newStatus, fmt.Errorf(\"failed to update resource in spec: %w\", err)\n\t}\n\n\tif err := updateContainerSpec(ctx, cntr.Container, newSpec); err != nil {\n\t\treturn newStatus, err\n\t}\n\tdefer func() {\n\t\tif retErr != nil {\n\t\t\tdeferCtx, deferCancel := ctrdutil.DeferContext()\n\t\t\tdefer deferCancel()\n\t\t\t// Reset spec on error.\n\t\t\tif err := updateContainerSpec(deferCtx, cntr.Container, oldSpec); err != nil {\n\t\t\t\tlog.G(ctx).WithError(err).Errorf(\"Failed to update spec %+v for container %q\", oldSpec, id)\n\t\t\t}\n\t\t} else {","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/internal/cri/server/container_update_resources.go#L78-L114","documentation":"To build the new spec, updateContainerResources reads the container's current OCI spec via cntr.Container.Spec(ctx). If that containerd API call fails, the error is wrapped as 'failed to get container spec'. This indicates a containerd/metadata or shim-level failure reading the spec, not a bad request.","triggerScenarios":"Container.Spec(ctx) fails because the container record is gone from the metadata store, the bolt DB is corrupted/locked, or the backing snapshotter/storage is unhealthy.","commonSituations":"containerd store corruption after unclean shutdown; container removed concurrently between the store Get and the Spec call; disk I/O failures on /var/lib/containerd.","solutions":["Inspect containerd logs for the wrapped inner error (metadata/store failure details)","Verify containerd data directory health (disk space, filesystem errors) and restart containerd","If the container record is broken, remove the container and recreate it"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"failed to get container spec\") { /* check store health */ }","preventionTips":["Monitor disk health","Graceful containerd restarts"],"tags":["containerd","cri","oci-spec","storage"],"backgroundTag":"container-spec-read-failed","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}