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
- Search the embedded *.yaml manifests for the URL/path and remove the stale or wrong entry so only one hash remains
- Ensure each manifest's filestores base is unique (no overlapping prefix bases for the same files)
- Regenerate conflicting manifests with tools/cmd/generatefileassets from authoritative SHA256SUMS
- 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
- Keep one authoritative manifest per filestore base; avoid prefix-overlapping bases
- Deduplicate file entries when regenerating manifests
- Pin asset URLs to paths covered by exactly one manifest
- Add a test asserting every well-known URL yields at most one hash
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
- cannot specify additional objects when multiple clusters are
- found multiple hosted zones matched name %q
- found multiple InternetGateways matching tags
- Found multiple NLBs with DNSName %q
- found multiple listeners matching %+v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/e0f007912c670197.
Report an issue: GitHub.