kubernetes/kops · error

found multiple matches for asset %q

Error message

found multiple matches for asset %q

What it means

GetHash collects SHA256 hashes of all manifest entries whose filestore base + relative name matches the requested canonicalURL. If more than one distinct hash is found, it refuses to guess and returns this error, signaling ambiguous or conflicting asset data.

Source

Thrown at pkg/assets/assetdata/data.go:72

			return fmt.Errorf("parsing embedded file %q: %w", p, err)
		}

		matches := manifest.Matches(canonicalURL.String())
		allMatches = append(allMatches, matches...)
		return nil
	}); err != nil {
		return nil, false, fmt.Errorf("walking embedded data: %w", err)
	}

	hashes := sets.New[string]()
	for _, match := range allMatches {
		hashes.Insert(match.SHA256)
	}
	if len(hashes) == 0 {
		return nil, false, nil
	}
	if len(hashes) > 1 {
		return nil, false, fmt.Errorf("found multiple matches for asset %q", canonicalURL)
	}
	h, err := hashing.FromString(hashes.UnsortedList()[0])
	if err != nil {
		return nil, false, err
	}
	return h, true, nil
}

type file struct {
	Name   string `json:"name,omitempty"`
	SHA256 string `json:"sha256,omitempty"`
}

type fileStore struct {
	Base string `json:"base,omitempty"`
}

type manifest struct {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Search the embedded *.yaml manifests for the URL/path and remove the stale or wrong entry so only one hash remains
  2. Ensure each manifest's filestores base is unique (no overlapping prefix bases for the same files)
  3. Regenerate conflicting manifests with tools/cmd/generatefileassets from authoritative SHA256SUMS
  4. Pin the asset URL to a path only covered by one manifest

Example fix

// before: two manifests both list the path with different hashes
// filestore base https://foo/bar in a.yaml and https://foo in b.yaml
// after: keep one authoritative manifest, delete or scope the other base
filestores:
- base: https://foo/bar   # only a.yaml
Defensive patterns

Strategy: try-catch

Validate before calling

// before lookup, ensure the URL is scoped to one filestore
urls := []string{assetURL}
for _, u := range urls {
	var hits int
	for _, base := range knownFilestoreBases {
		if strings.HasPrefix(u, base) { hits++ }
	}
	if hits > 1 { /* ambiguous URL: narrow it before calling GetHash */ }
}

Try / catch

h, found, err := assetdata.GetHash(u)
if err != nil && strings.Contains(err.Error(), "found multiple matches") {
	// pick an explicit single-source manifest or fix the duplicate entry upstream
	return err
}

Prevention

When it happens

Trigger: Calling assetdata.GetHash for a URL that matches entries in multiple embedded manifests, or duplicate files entries with different sha256 values under overlapping filestores whose Base values are prefixes of the URL.

Common situations: Two manifest YAMLs regenerated for different Kubernetes versions both cover the same filestore path; duplicate filestore bases (one a prefix of another) with divergent hashes; hand-edited manifests reintroducing stale entries.

Related errors


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