GoogleContainerTools/skaffold · error
nested customTemplate components are not supported in skaffo
Error message
nested customTemplate components are not supported in skaffold (%s)
What it means
Custom template components may be envTemplate, sha256, gitCommit, dateTime, or inputDigest — but a component that is itself a customTemplate is explicitly rejected. This prevents unbounded recursion in template evaluation, so Skaffold returns this error naming the offending component.
Source
Thrown at pkg/skaffold/tag/tagger_mux.go:122
case c.EnvTemplateTagger != nil:
components[name], _ = NewEnvTemplateTagger(c.EnvTemplateTagger.Template)
case c.ShaTagger != nil:
components[name] = &ChecksumTagger{}
case c.GitTagger != nil:
components[name], _ = NewGitCommit(c.GitTagger.Prefix, c.GitTagger.Variant, c.GitTagger.IgnoreChanges)
case c.DateTimeTagger != nil:
components[name] = NewDateTimeTagger(c.DateTimeTagger.Format, c.DateTimeTagger.TimeZone)
case c.InputDigest != nil:
graph := graph.ToArtifactGraph(runCtx.Artifacts())
inputDigest, _ := NewInputDigestTagger(runCtx, graph)
components[name] = inputDigest
case c.CustomTemplateTagger != nil:
return nil, fmt.Errorf("nested customTemplate components are not supported in skaffold (%s)", name)
default:
return nil, fmt.Errorf("unknown component for custom template: %s %+v", name, c)
}
}
return components, nil
}
View on GitHub (pinned to a1189de023)
Solutions
- Flatten the nested custom template into its primitive components at the top level
- Compute the inner template's value via envTemplate chaining or precomputed components instead
- Remove the nested customTemplate block
Example fix
// before
components:
- name: OUTER
customTemplate:
template: "{{.SHA}}"
components:
- name: SHA
sha256: {}
// after
components:
- name: SHA
sha256: {}
# then reference {{.SHA}} directly in the outer template Defensive patterns
Strategy: validation
Validate before calling
for _, c := range tp.CustomTemplateTagger.Components {
if c.Component.CustomTemplateTagger != nil {
return fmt.Errorf("component %q must not be a customTemplate", c.Name)
}
} Type guard
func isNestedCustom(c latest.TaggerComponent) bool {
return c.EnvTemplateTagger == nil && c.CustomTemplateTagger != nil
} Try / catch
t, err := tag.NewTaggerMux(runCtx)
if err != nil && strings.Contains(err.Error(), "nested customTemplate components are not supported") {
return fmt.Errorf("flatten nested custom template components: %w", err)
} Prevention
- Document/enforce that components must be primitive strategies only
- When refactoring templates for reuse, inline components instead of nesting
- Validate config against the skaffold JSON schema which disallows nesting
When it happens
Trigger: A tagPolicy.customTemplate.components entry whose `customTemplateTagger` field is set (nested custom template), encountered in CreateComponents.
Common situations: Misunderstanding component composition rules and nesting customTemplate for reuse; accidental YAML indentation making a nested block land as a component strategy.
Related errors
- creating components: %w
- multiple components with name %s
- unknown component for custom template: %s %+v
- custom tag not provided
- getting tagger: %w
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/5f4dc3acdfc62fe3.
Report an issue: GitHub.