GoogleContainerTools/skaffold · error

getting relative path of %s

Error message

getting relative path of %s

What it means

After glob matching succeeds, expandSrcGlobPatterns converts each matched absolute path to a workspace-relative path with filepath.Rel(workspace, f). If a matched file lies outside the workspace (making a relative path impossible/meaningless) Rel fails and Skaffold wraps it as 'getting relative path of <file>'. Docker COPY sources must live inside the build context, so this signals a pattern that escapes the workspace.

Source

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

			path := filepath.Join(workspace, p)
			if _, err := os.Stat(path); err == nil {
				fts = append(fts, FromTo{From: filepath.Clean(p), To: cpCmd.dest, ToIsDir: cpCmd.destIsDir, StartLine: cpCmd.startLine, EndLine: cpCmd.endLine})
				matchesOne = true
				continue
			}

			files, err := filepath.Glob(path)
			if err != nil {
				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) {

View on GitHub (pinned to a1189de023)

Solutions

  1. Ensure all COPY sources are inside the configured workspace/build context — remove '..' traversal from patterns
  2. Correct the workspace root in skaffold.yaml (context field) so it is the common ancestor of all copied files
  3. Replace '..'-style references by restructuring the project or using an additional artifact with its own context
  4. Check for symlinks inside the workspace that point outside and remove or relocate them

Example fix

// before (Dockerfile, workspace=./svc)
COPY ../shared/lib /lib
// after (set context: . and)
COPY svc/main ./main
COPY shared/lib /lib
Defensive patterns

Strategy: try-catch

Validate before calling

func sourcesInsideWorkspace(workspace string, srcs []string) error {
    absWs, err := filepath.Abs(workspace)
    if err != nil { return err }
    for _, s := range srcs {
        matches, _ := filepath.Glob(filepath.Join(absWs, s))
        for _, m := range matches {
            if !strings.HasPrefix(m, absWs+string(os.PathSeparator)) {
                return fmt.Errorf("pattern %q resolves outside workspace: %s", s, m)
            }
        }
    }
    return nil
}

Type guard

func withinWorkspace(workspace, file string) bool {
    absWs, err := filepath.Abs(workspace)
    if err != nil { return false }
    abs, err := filepath.Abs(file)
    return err == nil && strings.HasPrefix(abs, absWs+string(os.PathSeparator))
}

Try / catch

fts, err := skaffold.ReadCopyCmdsFromDockerfile(path, args, cfg, false)
if err != nil && strings.Contains(err.Error(), "getting relative path of") {
    return fmt.Errorf("a COPY source escapes the workspace; fix pattern or context: %w", err)
}

Prevention

When it happens

Trigger: A glob in a COPY source matches files under a parent directory (e.g. '../shared/x*' resolving outside workspace), or the workspace root passed to the API does not contain the matched files.

Common situations: Dockerfiles copying from sibling directories via '..' paths; a workspace/workspaceRoot misconfiguration in skaffold.yaml pointing at a subdirectory; symlinks in the build context resolving outside the workspace.

Related errors


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