GoogleContainerTools/skaffold · error

no valid tagger found for artifact: %q

Error message

no valid tagger found for artifact: %q

What it means

TaggerMux dispatches tag generation per artifact by looking up a Tagger in a map keyed by image name. This error means the requested artifact's ImageName was never registered in that map when the mux was built, so no tagger can produce a tag for it. It is thrown because the mux is constructed from the pipelines' artifact lists and only knows those exact image names.

Source

Thrown at pkg/skaffold/tag/tagger_mux.go:35

package tag

import (
	"context"
	"fmt"

	"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/graph"
	"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/runner/runcontext"
	"github.com/GoogleContainerTools/skaffold/v2/pkg/skaffold/schema/latest"
)

type TaggerMux struct {
	byImageName map[string]Tagger
}

func (t *TaggerMux) GenerateTag(ctx context.Context, image latest.Artifact) (string, error) {
	tagger, found := t.byImageName[image.ImageName]
	if !found {
		return "", fmt.Errorf("no valid tagger found for artifact: %q", image.ImageName)
	}
	return tagger.GenerateTag(ctx, image)
}

func NewTaggerMux(runCtx *runcontext.RunContext) (Tagger, error) {
	pipelines := runCtx.GetPipelines()
	m := make(map[string]Tagger)
	for _, p := range pipelines {
		t, err := getTagger(runCtx, &p.Build.TagPolicy)
		if err != nil {
			return nil, fmt.Errorf("creating tagger: %w", err)
		}
		for _, a := range p.Build.Artifacts {
			m[a.ImageName] = t
		}
	}
	return &TaggerMux{byImageName: m}, nil
}

View on GitHub (pinned to a1189de023)

Solutions

  1. Verify the artifact's ImageName exactly matches an artifact defined in skaffold.yaml (case- and tag-sensitive, no :tag suffix)
  2. Rebuild the TaggerMux via NewTaggerMux with the same RunContext that contains the artifact
  3. Add the missing artifact to the skaffold.yaml build.artifacts list

Example fix

// before
mux, _ := tag.NewTaggerMux(runCtx) // built from config A
tag, err := mux.GenerateTag(ctx, latest.Artifact{ImageName: "my-app"}) // not in config A

// after
mux, _ := tag.NewTaggerMux(runCtxWithMyApp) // run context that defines my-app
tag, err := mux.GenerateTag(ctx, latest.Artifact{ImageName: "my-app"})
Defensive patterns

Strategy: validation

Validate before calling

func artifactHasTagger(mux tag.Tagger, img string) bool {
    if tm, ok := mux.(*tag.TaggerMux); ok {
        return tm.HasTagger(img)
    }
    return true
}
// call before GenerateTag; skip/log artifacts that fail the check

Type guard

if tm, ok := mux.(*tag.TaggerMux); ok { /* tm is *tag.TaggerMux; check image membership */ }

Try / catch

img, err := mux.GenerateTag(ctx, artifact)
if err != nil {
    if strings.Contains(err.Error(), "no valid tagger found for artifact") {
        // fall back to sha256 tagger for unregistered images
        return fallbackTagger.GenerateTag(ctx, artifact)
    }
    return "", err
}

Prevention

When it happens

Trigger: Calling GenerateTag(ctx, image) with a latest.Artifact whose ImageName does not exactly match any artifact ImageName in the RunContext pipelines used to build the mux — e.g. an image built outside the skaffold config, a renamed image, or a mux reused across different run contexts.

Common situations: Image name typos in kustomize/helm manifests vs skaffold.yaml; artifacts generated dynamically at runtime; reusing a TaggerMux built from one config with artifacts from another; profile overrides that rename images.

Related errors


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