{"record":{"id":"b38bbd86d06b213e","repo":"containerd/containerd","slug":"unable-to-fetch-descriptor-s-which-reports-cont","errorCode":null,"errorMessage":"unable to fetch descriptor (%s) which reports content size of zero: %w","messagePattern":"unable to fetch descriptor \\((.+?)\\) which reports content size of zero: %w","errorType":"error_code","errorClass":"errdefs.ErrInvalidArgument","httpStatus":400,"severity":"error","filePath":"core/remotes/handlers.go","lineNumber":156,"sourceCode":"func Fetch(ctx context.Context, ingester content.Ingester, fetcher Fetcher, desc ocispec.Descriptor) error {\n\tlog.G(ctx).Debug(\"fetch\")\n\n\tcw, err := content.OpenWriter(ctx, ingester, content.WithRef(MakeRefKey(ctx, desc)), content.WithDescriptor(desc))\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer cw.Close()\n\n\tws, err := cw.Status()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif desc.Size == 0 {\n\t\t// most likely a poorly configured registry/web front end which responded with no\n\t\t// Content-Length header; unable (not to mention useless) to commit a 0-length entry\n\t\t// into the content store. Error out here otherwise the error sent back is confusing\n\t\treturn fmt.Errorf(\"unable to fetch descriptor (%s) which reports content size of zero: %w\", desc.Digest, errdefs.ErrInvalidArgument)\n\t}\n\tif ws.Offset == desc.Size {\n\t\t// If writer is already complete, commit and return\n\t\terr := cw.Commit(ctx, desc.Size, desc.Digest)\n\t\tif err != nil && !errdefs.IsAlreadyExists(err) {\n\t\t\treturn fmt.Errorf(\"failed commit on ref %q: %w\", ws.Ref, err)\n\t\t}\n\t\treturn err\n\t}\n\n\tif desc.Size == int64(len(desc.Data)) {\n\t\treturn content.Copy(ctx, cw, bytes.NewReader(desc.Data), desc.Size, desc.Digest)\n\t}\n\n\trc, err := fetcher.Fetch(ctx, desc)\n\tif err != nil {\n\t\treturn err\n\t}","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/core/remotes/handlers.go#L138-L174","documentation":"Fetch rejects a descriptor that reports Size 0, because a zero-length blob cannot be meaningfully committed to the content store and almost always indicates the registry responded without a Content-Length header (poorly configured front end or proxy). Throwing early here avoids a more confusing downstream error.","triggerScenarios":"Calling Fetch (via HandlerFunc/handlers) with a workspace descriptor whose desc.Size == 0 — typically when the registry or a web front end omitted Content-Length for the manifest/blob request.","commonSituations":"Registries behind proxies/CDNs that strip Content-Length; misconfigured reverse proxies; chunked responses to manifest GETs; self-hosted registries misconfigured with wrong headers.","solutions":["Fix the registry/proxy to return Content-Length headers for GETs (disable chunked re-encoding)","Check for proxies like nginx stripping headers; ensure Content-Length is passed through","Verify the image descriptor is valid in the source registry (re-pull manifest)","Use a registry that sets Content-Length correctly (Docker Hub, Harbor, recent distribution releases)"],"exampleFix":"// before: nginx proxy strips headers\n// proxy_pass http://registry;\n// after: pass Content-Length through\nlocation /v2/ {\n    proxy_pass http://registry;\n    proxy_set_header Content-Length $content_length;\n}","handlingStrategy":"validation","validationCode":"if desc.Size == 0 {\n    // fix registry/proxy config before fetching\n    return errors.New(\"descriptor reports zero size: registry not returning Content-Length\")\n}","typeGuard":"func hasValidSize(desc ocispec.Descriptor) bool {\n    return desc.Size > 0\n}","tryCatchPattern":"err := handlers.Fetch(ctx, ingester, fetcher, desc)\nif err != nil && strings.Contains(err.Error(), \"content size of zero\") {\n    // fix registry/proxy; try direct registry access bypassing front end\n    return fetchDirect(ctx, desc)\n}","preventionTips":["Verify registry front end passes Content-Length headers through","Test manifest/blob GETs with curl -I to confirm Content-Length present","Avoid proxies/CDN layers that chunk responses without length","Pin to recent registry distribution versions that set Content-Length"],"tags":["containerd","registry","http","content-store"],"backgroundTag":"zero-content-length-response","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}