GoogleContainerTools/skaffold · error

parsing dockerfile: %w

Error message

parsing dockerfile: %w

What it means

filterUnusedBuildArgs parses the Dockerfile to discover which ARG names it declares, then drops build-arg entries the file never uses. If parser.Parse fails here, the error is wrapped WITHOUT a file path ('parsing dockerfile: %w'), which makes it slightly harder to attribute — it is still a raw Dockerfile syntax failure. This path is reached from evalBuildArgs during image build configuration.

Source

Thrown at pkg/skaffold/docker/parse.go:156

			if err != nil {
				return nil, err
			}

			if cpCmd != nil && len(cpCmd.srcs) > 0 {
				for _, src := range cpCmd.srcs {
					copied = append(copied, FromTo{From: src, To: cpCmd.dest, ToIsDir: cpCmd.destIsDir, StartLine: cpCmd.startLine, EndLine: cpCmd.endLine})
				}
			}
		}
	}
	return copied, nil
}

// filterUnusedBuildArgs removes entries from the build arguments map that are not found in the dockerfile
func filterUnusedBuildArgs(dockerFile io.Reader, buildArgs map[string]*string) (map[string]*string, error) {
	res, err := parser.Parse(dockerFile)
	if err != nil {
		return nil, fmt.Errorf("parsing dockerfile: %w", err)
	}
	m := make(map[string]*string)
	for _, n := range res.AST.Children {
		if strings.ToLower(n.Value) != command.Arg {
			continue
		}
		k := strings.SplitN(n.Next.Value, "=", 2)[0]
		if v, ok := buildArgs[k]; ok {
			m[k] = v
		}
	}
	return m, nil
}

func expandBuildArgs(nodes []*parser.Node, buildArgs map[string]*string) error {
	args, err := util.EvaluateEnvTemplateMap(buildArgs)
	if err != nil {
		return fmt.Errorf("unable to evaluate build args: %w", err)

View on GitHub (pinned to a1189de023)

Solutions

  1. Fix the Dockerfile syntax named in the inner error (lint with hadolint or 'docker build --check')
  2. Because this message lacks the file path, search your pipeline for the dockerfile source being read at this point and validate it directly
  3. If content is generated at runtime, print/dump it on failure and inspect the offending line
  4. Run the parse path with a known-good minimal Dockerfile to confirm the problem is file content, not caller wiring

Example fix

// before
FROM base as  
// after
FROM base AS build
Defensive patterns

Strategy: validation

Validate before calling

func pruneArgsSafely(dockerFile io.Reader, buildArgs map[string]*string) (map[string]*string, error) {
    content, err := io.ReadAll(dockerFile)
    if err != nil { return nil, err }
    if _, err := parser.Parse(bytes.NewReader(content)); err != nil {
        return nil, fmt.Errorf("dockerfile content invalid before arg pruning: %w", err)
    }
    return parser.Parse(bytes.NewReader(content)) // proceed
}

Type guard

func dockerfileReaderIsValid(r io.Reader) bool {
    b, err := io.ReadAll(r)
    if err != nil { return false }
    _, perr := parser.Parse(bytes.NewReader(b))
    return perr == nil
}

Try / catch

m, err := skaffoldPruneArgs(r, buildArgs)
if err != nil && strings.Contains(err.Error(), "parsing dockerfile:") {
    return fmt.Errorf("inline/generated dockerfile content invalid (no path in message): %w", err)
}

Prevention

When it happens

Trigger: evalBuildArgs (or an anonymous caller) passes a dockerfile reader whose content parser.Parse rejects — same class of syntax problems as 320/321/324, but hit while pruning unused build args.

Common situations: The same broken Dockerfile that later fails the main parse; a programmatically generated Dockerfile string with a syntax bug; test fixtures or inline Dockerfile content that is invalid.

Related errors


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