GoogleContainerTools/skaffold · error
applying default repo to %q: %w
Error message
applying default repo to %q: %w
What it means
ApplyDefaultRepo wraps a failed attempt to rewrite an image tag so it is prefixed with the user's default repository (e.g. gcr.io/mine). It calls docker.SubstituteDefaultRepoIntoImage, and if that substitution fails (after successfully reading multi-level repo support), the original tag and the underlying error are wrapped. This lets callers like ImageTags report which image tag could not be remapped.
Source
Thrown at pkg/skaffold/deploy/util/util.go:69
var (
confirmHydrationDirOverride = prompt.ConfirmHydrationDirOverride
)
// ApplyDefaultRepo applies the default repo to a given image tag.
func ApplyDefaultRepo(globalConfig string, defaultRepo *string, tag string) (string, error) {
repo, err := config.GetDefaultRepo(globalConfig, defaultRepo)
if err != nil {
return "", fmt.Errorf("getting default repo: %w", err)
}
multiLevel, err := config.GetMultiLevelRepo(globalConfig)
if err != nil {
return "", fmt.Errorf("getting multi-level repo support: %w", err)
}
newTag, err := docker.SubstituteDefaultRepoIntoImage(repo, multiLevel, tag)
if err != nil {
return "", fmt.Errorf("applying default repo to %q: %w", tag, err)
}
return newTag, nil
}
// Update which images are logged, if the image is present in the provided deployer's artifacts.
func AddTagsToPodSelector(runnerBuilds []graph.Artifact, deployerArtifacts []graph.Artifact, podSelector *kubernetes.ImageList) {
// This implementation is mostly picked from v1 for fixing log duplication issue when multiple deployers are used.
// According to the original author "Each Deployer will be directly responsible for adding its deployed artifacts to the PodSelector
// by cross-referencing them against the list of images parsed out of the set of manifests they each deploy". Each deploy should only
// add its own deployed artifacts to the PodSelector to avoid duplicate logging when multi-deployers are used.
// This implementation only streams logs for the intersection of runnerBuilds and deployerArtifacts images, not all images from a deployer
// probably because at that time the team didn't want to stream logs from images not built by Skaffold, e.g. images from docker hub, but this
// may change. The initial implementation was using imageName as map key for getting shared elements, this was ok as deployerArtifacts were
// parsed out from skaffold config files in v1 and tag was not available if not specified. Now deployers don't own render responsibilities
// anymore, instead callers pass rendered manifests to deployers, we can only parse artifacts from these rendered manifests. The imageName
// from deployerArtifacts here has the default-repo value as prefix while the one from runnerBuilds doesn't. This discrepancy causes artifact.Tag
// fail to add into podSelector, which leads to podWatchers fail to get events from pods. As tags are available in deployerArtifacts now, so usingView on GitHub (pinned to a1189de023)
Solutions
- Check the wrapped inner error from SubstituteDefaultRepoIntoImage to see why the tag could not be rewritten
- Verify the default repository configured (e.g. via --default-repo or skaffold.yaml defaultRepo) is a valid registry path
- Confirm the image tag is a fully-qualified, parseable docker image reference (registry/name:tag)
- If the repo is known to be multi-level incompatible, set multiLevel accordingly instead of forcing substitution
Example fix
// before
newTag, err := docker.SubstituteDefaultRepoIntoImage(repo, multiLevel, tag)
if err != nil {
return "", fmt.Errorf("applying default repo to %q: %w", tag, err)
}
// after
newTag, err := docker.SubstituteDefaultRepoIntoImage(repo, multiLevel, tag)
if err != nil {
return "", fmt.Errorf("applying default repo to %q: %w", tag, err)
} Defensive patterns
Strategy: validation
Validate before calling
func validateTagForDefaultRepo(tag string) error {
if tag == "" {
return fmt.Errorf("empty image tag")
}
ref, err := docker.ParseReference(tag)
if err != nil {
return fmt.Errorf("cannot parse image tag %q: %w", tag, err)
}
return nil
} Try / catch
if _, err := ImageTags(...); err != nil {
if strings.Contains(err.Error(), "applying default repo") {
log.Warnf("default repo substitution failed: %v — using original tag", err)
return originalTag, nil
}
return err
} Prevention
- Validate image references are fully qualified before build output is consumed
- Keep the default-repo config simple and verified with a test push
- Log the full wrapped error chain to see SubstituteDefaultRepoIntoImage's cause
- Check multi-level repo support settings match your registry's path structure
When it happens
Trigger: Calling ApplyDefaultRepo (directly or via ImageTags) when docker.SubstituteDefaultRepoIntoImage returns an error for the given tag/repo combination — e.g. the tag cannot be parsed or is incompatible with the repo's multi-level support setting.
Common situations: Misconfigured default-repository setting in skaffold.yaml; image names with unexpected registries or nested paths that don't fit the multi-level repo rules; empty or malformed image tag passed in from build output.
Related errors
- error getting docker client: %s
- docker build options, secrets and ssh, require BuildKit - se
- unable to evaluate build args: %w
- Sync: Auto is not supported by the build of %s
- compiling name match regex
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/9a687bfa4c98cf3c.
Report an issue: GitHub.