kubernetes/kops · error

different targets for same file %s: %s vs %s

Error message

different targets for same file %s: %s vs %s

What it means

Two *CopyFile tasks sharing the same task name (target key) must also agree on TargetFile; if the existing task's TargetFile differs from the new one's, the same dedup key maps to two different destinations, so Copy fails fast rather than writing to an ambiguous target.

Source

Thrown at pkg/assets/assetcopy/copy.go:75

	for _, fileAsset := range fileAssets {
		if fileAsset.DownloadURL.String() != fileAsset.CanonicalURL.String() {
			copyFileTask := &CopyFile{
				Name:       fileAsset.CanonicalURL.String(),
				TargetFile: fileAsset.DownloadURL.String(),
				SourceFile: fileAsset.CanonicalURL.String(),
				SHA:        fileAsset.SHAValue.Hex(),
				VFSContext: vfsContext,
				Cluster:    cluster,
			}

			if existing, ok := tasks[copyFileTask.Name]; ok {
				e, ok := existing.(*CopyFile)
				if !ok {
					return fmt.Errorf("different types for copy target %s", copyFileTask.Name)
				}
				if e.TargetFile != copyFileTask.TargetFile {
					return fmt.Errorf("different targets for same file %s: %s vs %s", copyFileTask.Name, copyFileTask.TargetFile, e.TargetFile)
				}
				if e.SHA != copyFileTask.SHA {
					return fmt.Errorf("different sha for same file %s: %s vs %s", copyFileTask.Name, copyFileTask.SHA, e.SHA)
				}
			}

			tasks[copyFileTask.Name] = copyFileTask
		}
	}

	ch := make(chan error, 5)
	for i := 0; i < cap(ch); i++ {
		ch <- nil
	}

	gotError := false
	names := make([]string, 0, len(tasks))
	for name := range tasks {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Ensure the task name and TargetFile are derived from the same value so equal names imply equal targets
  2. Remove or rename duplicate file assets that share a name but disagree on destination
  3. Regenerate assets from a single consistent version so target paths match across entries
Defensive patterns

Strategy: validation

Validate before calling

fileTargets := map[string]string{}
for _, f := range fileAssets {
	if prev, ok := fileTargets[f.Name]; ok && prev != f.TargetFile {
		return fmt.Errorf("pre-check: task %s maps to targets %s and %s", f.Name, prev, f.TargetFile)
	}
	fileTargets[f.Name] = f.TargetFile
}

Type guard

func fileTargetsConsistent(files []FileAsset) bool {
	seen := map[string]string{}
	for _, f := range files {
		if p, ok := seen[f.Name]; ok && p != f.TargetFile {
			return false
		}
		seen[f.Name] = f.TargetFile
	}
	return true
}

Try / catch

if err := copy.Run(ctx); err != nil {
	if strings.Contains(err.Error(), "different targets for same file") {
		return fmt.Errorf("asset config bug: %w — one task name must map to one target path", err)
	}
	return err
}

Prevention

When it happens

Trigger: Two FileAssets whose task names collide but whose TargetFile fields differ, added in the same Copy invocation (e.g. assets built from nodeup/manifest assets lists with overlapping names).

Common situations: Asset name collisions after upgrading kOps where a file's target path changed but its key did not; templated target paths producing inconsistent values; duplicate entries in fileAssets config with differing destinations.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/6064f453e2d63136. Report an issue: GitHub.