GoogleContainerTools/skaffold · error
file pattern %s must match at least one file
Error message
file pattern %s must match at least one file
What it means
If a COPY source pattern matched zero files anywhere in the workspace, expandSrcGlobPatterns fails with 'file pattern %s must match at least one file'. Docker's build would also fail on such a COPY, so Skaffold surfaces it early during dependency computation. The message includes the full srcs list of the failing copy command.
Source
Thrown at pkg/skaffold/docker/parse.go:242
return nil, fmt.Errorf("invalid glob pattern: %w", err)
}
if files == nil {
continue
}
for _, f := range files {
rel, err := filepath.Rel(workspace, f)
if err != nil {
return nil, fmt.Errorf("getting relative path of %s", f)
}
fts = append(fts, FromTo{From: rel, To: cpCmd.dest, ToIsDir: cpCmd.destIsDir, StartLine: cpCmd.startLine, EndLine: cpCmd.endLine})
}
matchesOne = true
}
if !matchesOne {
return nil, fmt.Errorf("file pattern %s must match at least one file", cpCmd.srcs)
}
}
log.Entry(context.TODO()).Debugf("Found dependencies for dockerfile: %v", fts)
return fts, nil
}
func extractCopyCommands(ctx context.Context, nodes []*parser.Node, onlyLastImage bool, cfg Config) ([]*copyCommand, error) {
stages := map[string]bool{
"scratch": true,
}
slex := shell.NewLex('\\')
var copied []*copyCommand
workdir := "/"
envs := make([]string, 0)View on GitHub (pinned to a1189de023)
Solutions
- cd into the workspace and verify the path in the error actually exists (ls the pattern with the shell)
- Fix the COPY source path or glob in the Dockerfile to match the real file location
- Run the build/codegen step that generates the missing files before Skaffold computes dependencies
- Check filename case and workspace context in skaffold.yaml — the pattern is resolved relative to that context, not the repo root
Example fix
// before (Dockerfile) COPY dist/bundle.js /app/ // after (path verified against workspace) COPY build/output/bundle.js /app/
Defensive patterns
Strategy: validation
Validate before calling
func sourcesMatchAtLeastOneFile(workspace string, srcs []string) error {
for _, s := range srcs {
matches, err := filepath.Glob(filepath.Join(workspace, s))
if err != nil { return err }
if len(matches) == 0 {
return fmt.Errorf("COPY source %q matches no files under %s", s, workspace)
}
}
return nil
} Type guard
func globMatchesSomething(workspace, pattern string) bool {
matches, err := filepath.Glob(filepath.Join(workspace, pattern))
return err == nil && len(matches) > 0
} Try / catch
fts, err := skaffold.ReadCopyCmdsFromDockerfile(path, args, cfg, false)
if err != nil && strings.Contains(err.Error(), "must match at least one file") {
var srcs string
fmt.Sscanf(err.Error(), "file pattern %s must match", &srcs)
return fmt.Errorf("verify path exists under workspace (case-sensitive) or run codegen first: %s", srcs)
} Prevention
- Verify every COPY source with ls/glob from inside the workspace before building
- Check filename case — Linux resolution is case-sensitive
- Run codegen/build steps that produce copied artifacts before Skaffold dependency extraction
- After refactoring directory layouts, grep Dockerfiles for stale source paths
When it happens
Trigger: ReadCopyCmdsFromDockerfile (only when onlyLastImage/all-images mode requires existing files) hits a COPY whose source path/glob has no match on disk — wrong relative directory, file not built yet, case-mismatched filename, or pattern expecting generated output that does not exist yet.
Common situations: Case sensitivity (README.md vs readme.md on Linux); running dependency computation before a codegen step that produces the copied files; Dockerfile written for a different workspace layout than skaffold.yaml's context; typos or stale paths after refactoring.
Related errors
- invalid glob pattern: %w
- cannot find provided file %s
- reading global config: %w
- invalid exclude patterns: %w
- getting relative path of %s
AI-assisted analysis of GoogleContainerTools/skaffold@a1189de023 (2026-09-05).
Data as JSON: /api/errors/ac78b10f8b5abfbd.
Report an issue: GitHub.