{"record":{"id":"178064558f255fdb","repo":"kubernetes/kops","slug":"fetching-q-v","errorCode":null,"errorMessage":"fetching %q: %v","messagePattern":"fetching %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/assets/assetcopy/copyimage.go","lineNumber":55,"sourceCode":"func (e *CopyImage) Run() error {\n\tsource := e.SourceImage\n\ttarget := e.TargetImage\n\n\tsourceRef, err := name.ParseReference(source)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing reference %q: %v\", source, err)\n\t}\n\n\ttargetRef, err := name.ParseReference(target)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"parsing reference for %q: %v\", target, err)\n\t}\n\n\toptions := []remote.Option{remote.WithAuthFromKeychain(authn.DefaultKeychain)}\n\n\tdesc, err := remote.Get(sourceRef, options...)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"fetching %q: %v\", source, err)\n\t}\n\n\ttargetDesc, err := remote.Get(targetRef, options...)\n\tif err == nil && desc.Digest.String() == targetDesc.Digest.String() {\n\t\tklog.Infof(\"no need to copy image from %v to %v\", sourceRef, targetRef)\n\t\treturn nil\n\t}\n\n\tswitch desc.MediaType {\n\tcase types.OCIImageIndex, types.DockerManifestList:\n\t\t// Handle indexes separately.\n\t\tif err := copyIndex(desc, sourceRef, targetRef, options...); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to copy index: %v\", err)\n\t\t}\n\tdefault:\n\t\t// Assume anything else is an image, since some registries don't set mediaTypes properly.\n\t\tif err := copyImage(desc, sourceRef, targetRef, options...); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to copy image: %v\", err)","sourceCodeStart":37,"sourceCodeEnd":73,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/assets/assetcopy/copyimage.go#L37-L73","documentation":"remote.Get failed while fetching the source image's manifest descriptor from its registry. ParseReference succeeded, so the reference is syntactically fine; the failure is at the network/registry layer: DNS, connection, TLS, authentication (401/403), or the manifest simply does not exist (404 NAME_UNKNOWN / MANIFEST_UNKNOWN). kOps wraps it as \"fetching %q: %v\" using authn.DefaultKeychain for credentials.","triggerScenarios":"CopyImage.Run calls remote.Get(sourceRef) and the registry returns an error: image/tag/digest not present in the source repo, no network route, registry requires auth and no keychain credentials are configured (docker config / credential helper), rate limiting, or TLS problems with a private registry.","commonSituations":"Typos in image name or tag in the kops cluster spec (image never existed at that tag); running kops from a machine without internet or registry access; unauthenticated pulls of a private image (missing `docker login` / invalid ~/.docker/config.json); image moved or deleted upstream (e.g. registry.k8s.io restructuring); corporate proxy blocking registry.k8s.io.","solutions":["Verify the image exists: `crane manifest <source>` or `docker manifest inspect <source>`; fix the tag/digest in the cluster spec if it 404s.","Ensure registry credentials are available to authn.DefaultKeychain (`docker login <registry>`) and the credential helper works.","Check network/DNS/proxy connectivity to the registry host from the machine running kops.","Retry later if the registry is rate-limiting (e.g. Docker Hub 429)."],"exampleFix":"// before (no credentials, private source)\n# kops set cluster spec.assets... ; remote.Get -> 401\n// after\n$ docker login registry.k8s.io   # or your private registry\n$ kops update cluster ...        # re-run the copy","handlingStrategy":"try-catch","validationCode":"if out, err := exec.Command(\"crane\", \"digest\", sourceImage).CombinedOutput(); err != nil {\n\treturn fmt.Errorf(\"source image %q unreachable before copy: %v: %s\", sourceImage, err, out)\n}","typeGuard":null,"tryCatchPattern":"if err := e.Run(); err != nil {\n\tif strings.Contains(err.Error(), \"fetching\") {\n\t\tvar terr *net.OpError\n\t\tif errors.As(err, &terr) {\n\t\t\t// network-level: check DNS/proxy/firewall, then retry with backoff\n\t\t}\n\t\tif strings.Contains(err.Error(), \"401\") || strings.Contains(err.Error(), \"403\") {\n\t\t\t// re-authenticate: docker login <registry>, refresh credential helper\n\t\t}\n\t\tif strings.Contains(err.Error(), \"404\") || strings.Contains(err.Error(), \"not found\") {\n\t\t\t// fix the image tag/digest in the cluster spec\n\t\t}\n\t}\n\treturn err\n}","preventionTips":["Pre-check image existence with crane/docker manifest inspect before the copy.","Run `docker login` against both registries before kops update in CI.","Verify DNS/proxy reachability of registry hosts from the kops runner.","Pin images by digest to avoid tags disappearing upstream."],"tags":["network","registry","container-image","authentication"],"backgroundTag":"image-pull-registry-error","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}