GoogleContainerTools/skaffold · error

unable to expand build args: %w

Error message

unable to expand build args: %w

What it means

Wraps a failure from util.EvaluateEnvTemplateMapWithEnv when expanding ${...} templates in build args. A referenced environment variable is unset (or a template is malformed), so the final build-arg map cannot be produced.

Source

Thrown at pkg/skaffold/docker/build_args.go:86

	absDockerfilePath, err := NormalizeDockerfilePath(workspace, dockerfilePath)
	if err != nil {
		return nil, fmt.Errorf("normalizing dockerfile path: %w", err)
	}
	f, err := os.Open(absDockerfilePath)
	if err != nil {
		return nil, fmt.Errorf("reading dockerfile: %w", err)
	}
	defer f.Close()
	result, err = filterUnusedBuildArgs(f, result)
	if err != nil {
		return nil, fmt.Errorf("removing unused default args: %w", err)
	}
	for k, v := range args {
		result[k] = v
	}
	result, err = util.EvaluateEnvTemplateMapWithEnv(result, env)
	if err != nil {
		return nil, fmt.Errorf("unable to expand build args: %w", err)
	}
	return result, nil
}

// ArtifactResolver provides an interface to resolve built artifact tags by image name.
type ArtifactResolver interface {
	GetImageTag(imageName string) (string, bool)
}

// ResolveDependencyImages creates a map of artifact aliases to their built image from a required artifacts slice.
// If `missingIsFatal` is false then it is permissive of missing entries in the ArtifactResolver and returns nil for those entries.
func ResolveDependencyImages(deps []*latest.ArtifactDependency, r ArtifactResolver, missingIsFatal bool) map[string]*string {
	if r == nil {
		// `diagnose` is called without an artifact resolver. Return an empty map in this case.
		return nil
	}
	m := make(map[string]*string)
	for _, d := range deps {

View on GitHub (pinned to a1189de023)

Solutions

  1. Export the missing environment variable before running skaffold
  2. Use a default in the template: ${VAR:-default}
  3. Hard-code the value in skaffold.yaml if it is static
  4. Fix malformed template syntax in the build-arg value

Example fix

// before
build:
  buildArgs:
    USER: "{{.USER}}"   # unset in CI
// after
build:
  buildArgs:
    USER: "${USER:-ci}"
Defensive patterns

Strategy: validation

Validate before calling

for k, v := range buildArgs {
  for _, m := range templateRegexp.FindAllStringSubmatch(v, -1) {
    name := m[1]
    if os.Getenv(name) == "" && !strings.Contains(v, name+":-") {
      return fmt.Errorf("build arg %s references unset env var %s", k, name)
    }
  }
}

Try / catch

args, err := evalBuildArgs(workspace, df, args, env)
if err != nil && strings.Contains(err.Error(), "unable to expand build args") {
  return fmt.Errorf("missing env var for build args: %w", err)
}

Prevention

When it happens

Trigger: evalBuildArgs calls EvaluateEnvTemplateMapWithEnv(result, env) and a build arg value like ${USER} or ${VAR:-default} with an unset required variable fails evaluation, or the template syntax is invalid.

Common situations: skaffold.yaml build args referencing env vars absent in CI; shell-expanded vars available locally but not in the build environment; typos like ${{VAR}}.

Understand the failure class

Background: "environment variable is not set" and "Missing keys in environment" errors: what missing required env var messages mean and how to fix them — this error's family across 28 libraries.

Related errors


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