GoogleContainerTools/skaffold · error

duplicate image %q found in sources %s and %s: artifact imag

Error message

duplicate image %q found in sources %s and %s: artifact image names must be unique across all configurations

What it means

validateImageNames enforces that artifact image names are unique across ALL configurations in a multi-config skaffold project. When an artifact's ImageName was already registered from another (or the same) source file, it records an ErrorWithLocation pointing at the current occurrence's YAML lines, listing both source files. This is the 'current location' variant of the duplicate report.

Source

Thrown at pkg/skaffold/schema/validation/validation.go:165

			})
		}
	}
	return
}

// validateImageNames makes sure the artifact image names are unique and valid base names,
// without tags nor digests.
func validateImageNames(configs parser.SkaffoldConfigSet) (errs []ErrorWithLocation) {
	seen := make(map[string]string)
	arMap := make(map[string]*latest.Artifact)

	for _, c := range configs {
		for i, a := range c.Build.Artifacts {
			curLines := c.YAMLInfos.Locate(c.Build.Artifacts[i])
			if prevSource, found := seen[a.ImageName]; found {
				prevLines := c.YAMLInfos.Locate(arMap[c.Build.Artifacts[i].ImageName])
				errs = append(errs, ErrorWithLocation{
					Error: fmt.Errorf("duplicate image %q found in sources %s and %s: artifact image names must be unique across all configurations",
						a.ImageName, prevSource, c.SourceFile),
					Location: curLines,
				})
				errs = append(errs, ErrorWithLocation{
					Error: fmt.Errorf("duplicate image %q found in sources %s and %s: artifact image names must be unique across all configurations",
						a.ImageName, prevSource, c.SourceFile),
					Location: prevLines,
				})
				continue
			}

			seen[a.ImageName] = c.SourceFile
			arMap[a.ImageName] = a
			parsed, err := docker.ParseReference(a.ImageName)
			if err != nil {
				errs = append(errs, wrapWithContext(c, ErrorWithLocation{
					Error:    fmt.Errorf("invalid image %q: %w", a.ImageName, err),
					Location: curLines,

View on GitHub (pinned to a1189de023)

Solutions

  1. Rename one of the duplicate artifacts' image name so each is unique across all configs
  2. Check which files the message names (sources A and B) and remove the redundant artifact definition
  3. If intentional reuse, factor the artifact into a shared config and reference it instead of duplicating

Example fix

# before (two configs)
build:
  artifacts:
    - image: app
# after
build:
  artifacts:
    - image: frontend-app
Defensive patterns

Strategy: validation

Validate before calling

func checkUniqueImages(configs []*latest.SkaffoldConfig) error {
	seen := map[string]string{}
	for _, c := range configs {
		for _, a := range c.Build.Artifacts {
			if prev, ok := seen[a.ImageName]; ok {
				return fmt.Errorf("duplicate image %q in %s and %s", a.ImageName, prev, c.SourceFile)
			}
			seen[a.ImageName] = c.SourceFile
		}
	}
	return nil
}

Try / catch

var locErr []validation.ErrorWithLocation
if err := validation.ProcessErrors(errs); err != nil { /* use ErrorWithLocation to surface file:line */ }

Prevention

When it happens

Trigger: Running validation (via skaffold config load/parse) when two artifacts in different configs (or config + dependency overrides) declare the same image: name.

Common situations: Merging multiple skaffold.yaml configs where two teams independently named an artifact 'app'; a remote dependency config re-declaring an image already defined locally.

Related errors


AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05). Data as JSON: /api/errors/6be0298f8a9c8428. Report an issue: GitHub.