docker/compose · error

unable to prepare context: %w

Error message

unable to prepare context: %w

What it means

Wraps the error from build.GetContextFromLocalDir when the detected context type is a local path but the directory (or the Dockerfile within it) cannot be resolved. GetContextFromLocalDir validates that the context is an existing directory and that the absolute Dockerfile path lives under it; any failure is re-wrapped with 'unable to prepare context' plus the underlying cause.

Source

Thrown at pkg/compose/build_classic.go:170

	service.Build.Labels[api.ImageBuilderLabel] = "classic"

	dockerfileName := dockerFilePath(service.Build.Context, service.Build.Dockerfile)
	specifiedContext := service.Build.Context
	progBuff := s.stdout()
	buildBuff := s.stdout()

	contextType, err := build.DetectContextType(specifiedContext)
	if err != nil {
		return "", err
	}

	switch contextType {
	case build.ContextTypeStdin:
		return "", fmt.Errorf("building from STDIN is not supported")
	case build.ContextTypeLocal:
		contextDir, relDockerfile, err = build.GetContextFromLocalDir(specifiedContext, dockerfileName)
		if err != nil {
			return "", fmt.Errorf("unable to prepare context: %w", err)
		}
		if strings.HasPrefix(relDockerfile, ".."+string(filepath.Separator)) {
			// Dockerfile is outside build-context; read the Dockerfile and pass it as dockerfileCtx
			dockerfileCtx, err = os.Open(dockerfileName)
			if err != nil {
				return "", fmt.Errorf("unable to open Dockerfile: %w", err)
			}
			defer dockerfileCtx.Close() //nolint:errcheck
		}
	case build.ContextTypeGit:
		var tempDir string
		tempDir, relDockerfile, err = build.GetContextFromGitURL(specifiedContext, dockerfileName)
		if err != nil {
			return "", fmt.Errorf("unable to prepare context: %w", err)
		}
		defer func() {
			_ = os.RemoveAll(tempDir)
		}()

View on GitHub (pinned to ddc4b044b6)

Solutions

  1. Verify the context directory exists: `ls <context path>` from the same directory you run `docker compose build`
  2. Fix the `build.context` / `build.dockerfile` values in the Compose file (check spelling, case, and relative-path base)
  3. If the path is interpolated (`context: ${VAR}`), confirm the variable is set and non-empty in the shell or .env file

Example fix

# before
services:
  app:
    build:
      context: ./backendd   # typo

# after
services:
  app:
    build:
      context: ./backend
Defensive patterns

Strategy: validation

Validate before calling

info, err := os.Stat(svc.Build.Context)
if err != nil || !info.IsDir() {
    return fmt.Errorf("build context %q is not an existing directory", svc.Build.Context)
}
if df := svc.Build.Dockerfile; df != "" {
    if _, err := os.Stat(filepath.Join(svc.Build.Context, df)); err != nil {
        return fmt.Errorf("dockerfile %q not found in context: %w", df, err)
    }
}

Try / catch

if err := compose.Build(ctx, project, opts); err != nil {
    if strings.Contains(err.Error(), "unable to prepare context") {
        // surface the chained fs error, point user at context/dockerfile paths
    }
}

Prevention

When it happens

Trigger: `docker compose build` where build.context points to a non-existent or non-directory path, or build.dockerfile names a file that cannot be stat'ed relative to the context (e.g. context typo, wrong working directory, missing checkout of a monorepo sibling dir).

Common situations: Context paths that depend on where you run compose from (relative paths like ../backend); monorepo checkouts where only part was cloned; Dockerfile key misspelled (`dockerfile: Dockerfile.prod` when the file is named differently); case-sensitivity issues moving from macOS to Linux CI.

Related errors


AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15). Data as JSON: /api/errors/9b1be8534d9fba9d. Report an issue: GitHub.