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

  1. Flatten the nested custom template into its primitive components at the top level
  2. Compute the inner template's value via envTemplate chaining or precomputed components instead
  3. 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

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


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