GoogleContainerTools/skaffold · error

unsupported docker command found for DockerfileCommandLinter

Error message

unsupported docker command found for DockerfileCommandLinter: %v

What it means

DockerfileCommandLinter only knows how to lint ADD and COPY commands (it treats them identically). If a DockerCommandFilter rule targets any other Docker command, the linter logs and returns this error instead of silently skipping the rule. It signals an unsupported command in the rule configuration.

Source

Thrown at pkg/skaffold/lint/linters.go:58

	fromTos, err := readCopyCmdsFromDockerfile(context.TODO(), false, params.ConfigFile.AbsPath, params.WorkspacePath, map[string]*string{}, params.DockerConfig)
	if err != nil {
		return nil, err
	}
	for _, rule := range *rules {
		if rule.RuleType != DockerfileCommandLintRule {
			continue
		}
		var dockerCommandFilter DockerCommandFilter
		switch v := rule.Filter.(type) {
		case DockerCommandFilter:
			dockerCommandFilter = v
		default:
			return nil, fmt.Errorf("unknown filter type found for DockerfileCommandLinter lint rule: %v", rule)
		}
		// NOTE: ADD and COPY are both treated the same from the linter perspective - eg: if you have linter look at COPY src/dest it will also check ADD src/dest
		if dockerCommandFilter.DockerCommand != command.Copy && dockerCommandFilter.DockerCommand != command.Add {
			log.Entry(context.TODO()).Errorf("unsupported docker command found for DockerfileCommandLinter: %v", dockerCommandFilter.DockerCommand)
			return nil, fmt.Errorf("unsupported docker command found for DockerfileCommandLinter: %v", dockerCommandFilter.DockerCommand)
		}
		for _, fromTo := range fromTos {
			r, err := regexp.Compile(dockerCommandFilter.DockerCopySourceRegExp)
			if err != nil {
				return nil, err
			}
			if !r.MatchString(fromTo.From) {
				continue
			}
			log.Entry(context.TODO()).Infof("docker command 'copy' match found for source: %s\n", fromTo.From)
			// TODO(aaron-prindle) modify so that there are input and output params s.t. it is more obvious what fields need to be updated
			params.DockerCopyCommandInfo = fromTo
			appendRuleIfConditionsAndExplanationPopulationsSucceed(params, results, rule, fromTo.StartLine, 1, fromTo.EndLine, 0)
		}
	}
	return results, nil
}

View on GitHub (pinned to a1189de023)

Solutions

  1. Change the rule's DockerCommand to command.Copy or command.Add, which are the only supported commands
  2. Register the rule with a linter that supports the target Docker command
  3. Add/extend linter support for the command before using it in a filter

Example fix

// before
DockerCommandFilter{DockerCommand: command.Run}
// after
DockerCommandFilter{DockerCommand: command.Copy, DockerCopySourceRegExp: "src/"}
Defensive patterns

Strategy: validation

Validate before calling

func isLinterSupportedCommand(dcf DockerCommandFilter) bool {
    return dcf.DockerCommand == command.Copy || dcf.DockerCommand == command.Add
}
if !isLinterSupportedCommand(rule.Filter.(DockerCommandFilter)) {
    return fmt.Errorf("route rule %v to a command-aware linter instead", rule)
}

Type guard

func isCopyOrAdd(d DockerCommand) bool { return d == command.Copy || d == command.Add }

Prevention

When it happens

Trigger: A lint rule whose DockerCommandFilter.DockerCommand is anything other than command.Copy or command.Add (e.g. RUN, ENV, ENTRYPOINT) reaches the command check in Lint.

Common situations: Authoring a custom linter rule for RUN or another instruction and registering it with DockerfileCommandLinter instead of a command-aware linter; typos in command names; version changes where commands were added before the linter supported them.

Related errors


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