{"record":{"id":"d9618731691d8377","repo":"containerd/containerd","slug":"no-push-hosts-w","errorCode":null,"errorMessage":"no push hosts: %w","messagePattern":"no push hosts: %w","errorType":"error_code","errorClass":"errdefs.ErrNotFound","httpStatus":404,"severity":"error","filePath":"core/remotes/docker/pusher.go","lineNumber":109,"sourceCode":"\tstatus, err := p.tracker.GetStatus(ref)\n\tif err == nil {\n\t\tif status.Committed && status.Offset == status.Total {\n\t\t\treturn nil, fmt.Errorf(\"ref %v: %w\", ref, errdefs.ErrAlreadyExists)\n\t\t}\n\t\tif unavailableOnFail && status.ErrClosed == nil {\n\t\t\t// Another push of this ref is happening elsewhere. The rest of function\n\t\t\t// will continue only when `errdefs.IsNotFound(err) == true` (i.e. there\n\t\t\t// is no actively-tracked ref already).\n\t\t\treturn nil, fmt.Errorf(\"push is on-going: %w\", errdefs.ErrUnavailable)\n\t\t}\n\t\t// TODO: Handle incomplete status\n\t} else if !errdefs.IsNotFound(err) {\n\t\treturn nil, fmt.Errorf(\"failed to get status: %w\", err)\n\t}\n\n\thosts := p.filterHosts(HostCapabilityPush)\n\tif len(hosts) == 0 {\n\t\treturn nil, fmt.Errorf(\"no push hosts: %w\", errdefs.ErrNotFound)\n\t}\n\n\tvar (\n\t\tisManifest bool\n\t\texistCheck []string\n\t\thost       = hosts[0]\n\t)\n\n\tif images.IsManifestType(desc.MediaType) || images.IsIndexType(desc.MediaType) {\n\t\tisManifest = true\n\t\texistCheck = getManifestPath(p.object, desc.Digest)\n\t} else {\n\t\texistCheck = []string{\"blobs\", desc.Digest.String()}\n\t}\n\n\treq := p.request(host, http.MethodHead, existCheck...)\n\tif err := req.addNamespace(p.refspec.Hostname()); err != nil {\n\t\treturn nil, err","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/containerd/containerd/blob/4246446a2bf7d03837b0244118d858799393bd80/core/remotes/docker/pusher.go#L91-L127","documentation":"containerd's docker pusher filters its configured registry hosts down to those with the push capability. If no host declares push capability, push() aborts immediately with errdefs.ErrNotFound wrapped in this message before any network request is made. It means the remotes configuration simply has no usable push endpoint, not a network or auth problem.","triggerScenarios":"Calling Writer (content store writer) or Push with a resolver/host config where every configured host lacks HostCapabilityPush — e.g. hosts built as mirror/pull-only, or an empty hosts list for the registry.","commonSituations":"Configuring containerd with registry.mirrors (pull-only) and then trying to push; using a client.Config host entry without docker.HostCapabilityPush; pushing through a proxy endpoint that was set up solely for pulling; mis-resolved default host (e.g. docker.io not configured).","solutions":["Add or fix the host configuration so at least one host includes docker.HostCapabilityPush in its Capabilities.","Verify the registry host is actually configured for the reference's hostname (check containerd config.toml [plugins.\"io.containerd.grpc.v1.cri\".registry] or client.WithRegistryHost).","If you only intend to pull, switch the operation to a pull path; push cannot proceed without a push-capable host.","Confirm you are not overriding hosts with client.WithScheme/WithHosts incorrectly (scheme/host typo can yield an empty match)."],"exampleFix":"// before\nhosts := []docker.Host{{Host: \"mirror.example.com\", Capabilities: docker.HostCapabilityPull}}\n// after\nhosts := []docker.Host{{Host: \"registry.example.com\", Capabilities: docker.HostCapabilityPull | docker.HostCapabilityPush}}","handlingStrategy":"validation","validationCode":"// before pushing, verify a push-capable host exists for the ref\nhosts := pusherConfig.Hosts(refspec.Hostname())\nif len(hosts) == 0 {\n    return fmt.Errorf(\"no host configured for %s\", refspec.Hostname())\n}\nfor _, h := range hosts {\n    if h.Capabilities&docker.HostCapabilityPush != 0 {\n        return nil // ok\n    }\n}\nreturn fmt.Errorf(\"no push-capable host for %s\", refspec.Hostname())","typeGuard":null,"tryCatchPattern":"if err := pusher.Push(ctx, desc); err != nil {\n    if strings.Contains(err.Error(), \"no push hosts\") {\n        // fix host config, do not retry\n    }\n    return err\n}","preventionTips":["Always include HostCapabilityPush in host capabilities for registries you intend to push to","Mirror-only configs are pull-only: use a separate push-capable host entry","Unit-test host resolution for each registry hostname you push to"],"tags":["containerd","registry","push","configuration"],"backgroundTag":"no-push-capable-registry-host","analyzedSha":"4246446a2bf7d03837b0244118d858799393bd80","analyzedAt":"2026-09-02T00:14:43.053Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}