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
- Verify the context directory exists: `ls <context path>` from the same directory you run `docker compose build`
- Fix the `build.context` / `build.dockerfile` values in the Compose file (check spelling, case, and relative-path base)
- 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
- Always run compose from the repo root or set --project-directory explicitly
- Add a preflight check (make target) that stats every build.context and dockerfile
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
- unable to prepare context: path %q not found
- building from STDIN is not supported
- unable to open Dockerfile: %w
- checking context: %w
- invalid ssh key %q
AI-assisted analysis of docker/compose@ddc4b044b6 (2026-08-15).
Data as JSON: /api/errors/9b1be8534d9fba9d.
Report an issue: GitHub.