kubernetes/kops · error
%s: %v
Error message
%s: %v
What it means
Copy() runs each asset copy task in a bounded worker-slot goroutine (cap-5 buffered channel used as a semaphore). When a task's Run() fails, the error is wrapped with the asset name via fmt.Errorf("%s: %v", n, err) before being sent on the channel, so the klog warning names which asset failed. It is a wrapper, not a root cause; the underlying error follows the colon.
Source
Thrown at pkg/assets/assetcopy/copy.go:107
}
gotError := false
names := make([]string, 0, len(tasks))
for name := range tasks {
names = append(names, name)
}
sort.Strings(names)
for _, name := range names {
task := tasks[name]
err := <-ch
if err != nil {
klog.Warning(err)
gotError = true
}
go func(n string, t assetTask) {
err := t.Run()
if err != nil {
err = fmt.Errorf("%s: %v", n, err)
}
ch <- err
}(name, task)
}
for i := 0; i < cap(ch); i++ {
err := <-ch
if err != nil {
klog.Warning(err)
gotError = true
}
}
close(ch)
if gotError {
return fmt.Errorf("not all assets copied successfully")
}
return nilView on GitHub (pinned to 4c8573c808)
Solutions
- Read the asset name prefix, then diagnose the underlying error after the colon (often 'unable to transfer ...' or an upload/write error).
- Verify the source asset URL is reachable from the machine running kops (curl/HEAD the canonical URL).
- Re-run `kops get assets --copy`; the channel-based task loop retries only on a fresh invocation.
- If the same asset fails repeatedly, check the asset's sha in the cluster spec against the actual upstream file.
Example fix
// before (observed log) W https://storage.googleapis.com/k8s-artifacts-prod/kube-proxy.tar.gz: unable to transfer ... : context deadline exceeded // after (fix upstream cause, e.g. retry with network access restored) kops get assets --copy --output <spec> # succeeds once source is reachable
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check that each asset's source URL is reachable before copying:
for _, name := range assetNames {
resp, err := http.Head(sourceURL(name))
if err != nil || resp.StatusCode >= 400 {
log.Printf("asset %s unreachable: %v", name, err)
}
} Type guard
// Go has no runtime type guard needed; narrow the wrapped error by inspecting the message prefix:
func assetNameFromError(err error) (string, bool) {
if err == nil { return "", false }
if i := strings.Index(err.Error(), ": "); i > 0 { return err.Error()[:i], true }
return "", false
} Try / catch
if err := assetcopy.Copy(imageAssets, fileAssets, vfsContext, cluster); err != nil {
// per-asset failures were already klog.Warning'd with "<asset>: <cause>"
return fmt.Errorf("asset copy incomplete, see warnings above: %w", err)
} Prevention
- Run kops from a host with egress to all upstream asset hosts
- Pre-verify asset URLs with curl -I before bulk copy
- Use -v=4 to get per-asset diagnostics
- Re-run after transient failures; matching assets are skipped
When it happens
Trigger: Any failure returned by CopyFile.Run() or CopyImage.Run() during `kops get assets --copy` — e.g. download failure, sha mismatch, or upload failure — is prefixed with the asset's canonical URL/name at copy.go:107.
Common situations: A single unreachable file repository or container registry among many assets; one corrupted asset whose sha does not match; transient network errors while copying hundreds of assets.
Related errors
- unable to transfer %q to %q: %v
- not all assets copied successfully
- unhandled sha length for %q
- error building path %q: %v
- unable to parse sha: %q, %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/00e4f3403a93f66a.
Report an issue: GitHub.