{"record":{"id":"c00dec93de8a02df","repo":"docker/compose","slug":"unable-to-open-dockerfile-w","errorCode":null,"errorMessage":"unable to open Dockerfile: %w","messagePattern":"unable to open Dockerfile: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/compose/build_classic.go","lineNumber":176,"sourceCode":"\n\tcontextType, err := build.DetectContextType(specifiedContext)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tswitch contextType {\n\tcase build.ContextTypeStdin:\n\t\treturn \"\", fmt.Errorf(\"building from STDIN is not supported\")\n\tcase build.ContextTypeLocal:\n\t\tcontextDir, relDockerfile, err = build.GetContextFromLocalDir(specifiedContext, dockerfileName)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"unable to prepare context: %w\", err)\n\t\t}\n\t\tif strings.HasPrefix(relDockerfile, \"..\"+string(filepath.Separator)) {\n\t\t\t// Dockerfile is outside build-context; read the Dockerfile and pass it as dockerfileCtx\n\t\t\tdockerfileCtx, err = os.Open(dockerfileName)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", fmt.Errorf(\"unable to open Dockerfile: %w\", err)\n\t\t\t}\n\t\t\tdefer dockerfileCtx.Close() //nolint:errcheck\n\t\t}\n\tcase build.ContextTypeGit:\n\t\tvar tempDir string\n\t\ttempDir, relDockerfile, err = build.GetContextFromGitURL(specifiedContext, dockerfileName)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"unable to prepare context: %w\", err)\n\t\t}\n\t\tdefer func() {\n\t\t\t_ = os.RemoveAll(tempDir)\n\t\t}()\n\t\tcontextDir = tempDir\n\tcase build.ContextTypeRemote:\n\t\tbuildCtx, relDockerfile, err = build.GetContextFromURL(progBuff, specifiedContext, dockerfileName)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"unable to prepare context: %w\", err)\n\t\t}","sourceCodeStart":158,"sourceCodeEnd":194,"githubUrl":"https://github.com/docker/compose/blob/ddc4b044b62e9f715212ea4143fa830fac76382f/pkg/compose/build_classic.go#L158-L194","documentation":"After GetContextFromLocalDir succeeds, doBuildClassic special-cases a Dockerfile that resolves outside the build context (relDockerfile starts with '../'): it must open that file with os.Open to pass it separately as dockerfileCtx. If os.Open fails (file deleted between stat and open, permission denied, dangling symlink), this wrapped error is returned.","triggerScenarios":"A Compose build where `build.dockerfile` is an absolute path or relative path outside the context directory, and that file is unreadable — wrong permissions, nonexistent, or a broken symlink — at the moment the classic builder runs.","commonSituations":"Shared Dockerfile at repo root with per-service contexts (`context: services/api`, `dockerfile: ../../Dockerfile`); files made unreadable by restrictive umask or owned by another user in CI; a symlink to a Dockerfile that exists only on the developer's machine.","solutions":["Confirm the Dockerfile path is readable: `cat <path-to-dockerfile>` from the compose invocation directory","Fix permissions (chmod 644) or repair/remove the symlink pointing at the Dockerfile","Move (or copy) the Dockerfile inside the build context and reference it relatively, which also removes the outside-context special case"],"exampleFix":"# before\nservices:\n  api:\n    build:\n      context: ./services/api\n      dockerfile: ../../Dockerfile.api  # unreadable/outside\n\n# after\nservices:\n  api:\n    build:\n      context: .\n      dockerfile: Dockerfile.api","handlingStrategy":"validation","validationCode":"// when the Dockerfile sits outside the context, verify it is readable up front\nabsCtx, _ := filepath.Abs(svc.Build.Context)\nabsDf, _ := filepath.Abs(filepath.Join(svc.Build.Context, svc.Build.Dockerfile))\nif strings.HasPrefix(absDf, absCtx+string(filepath.Separator)) == false {\n    if f, err := os.Open(absDf); err != nil {\n        return fmt.Errorf(\"dockerfile %q unreadable: %w\", absDf, err)\n    } else { _ = f.Close() }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep Dockerfiles inside their build context to avoid the outside-context branch entirely","Check file permissions of shared Dockerfiles in Dockerfiles-as-code lint steps"],"tags":["build","dockerfile","filesystem","permissions"],"backgroundTag":null,"analyzedSha":"ddc4b044b62e9f715212ea4143fa830fac76382f","analyzedAt":"2026-08-15T13:31:42.319Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}