docker/cli · error

unable to prepare context from STDIN

Error message

unable to prepare context from STDIN: %w

What it means

Returned by runBuild (build.go:233) when build.GetContextFromRead fails while reading the build context from stdin (ContextTypeStdin). GetContextFromRead reads stdin, detects compression, and produces a tar archive plus the relative Dockerfile path. Failure means the stdin stream could not be parsed as a valid (optionally compressed) tar build context.

Solutions

  1. If you only have a Dockerfile, pass it via -f- with a separate context: 'docker build -f- . <<EOF ... EOF'.
  2. If you intend a tar context, produce a valid tar: 'tar -czf - . | docker build -'.
  3. Verify the stream is not truncated: pipe through 'tar -tzf -' first to confirm it is a readable archive.
  4. Avoid piping non-archive content; use a local directory path as the context instead.

Example fix

# before (wrong: raw Dockerfile text to stdin context)
cat Dockerfile | docker build -
# after (local dir context, Dockerfile from stdin)
docker build -f- . < Dockerfile
# or: send a real tar archive
tar -czf - . | docker build -
Defensive patterns

Strategy: validation

Validate before calling

// Detect whether stdin is a usable (compressed) tar before building with '-'.
func stdinLooksLikeTar(r io.Reader) bool {
	br := bufio.NewReader(r)
	b, _ := br.Peek(2)
	// gzip magic 1f 8b or raw tar magic at offset 257 handled elsewhere
	return len(b) >= 2 && b[0] == 0x1f && b[1] == 0x8b
}

Try / catch

if err := buildCmd.Execute(); err != nil {
	if strings.Contains(err.Error(), "unable to prepare context from STDIN") {
		// stdin was not a valid tar context; switch to a local dir or -f- for Dockerfile-only
	}
}

Prevention

When it happens

Trigger: Piping a non-tar/non-archive stream to 'docker build -' (e.g., 'cat Dockerfile | docker build -'), sending corrupted/truncated gzip data, or interrupting the stdin stream mid-transfer. Also fires when the stream is a tar but the internal Dockerfile path cannot be resolved.

Common situations: Confusing the build-context-from-stdin convention: users often think '-' reads a Dockerfile from stdin, but with a positional '-' the CLI expects a full tar context; piping raw Dockerfile text; network/SSH stream corruption; running 'docker build -' interactively and closing the pipe early.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/10cb3eddcecbe48f. Report an issue: GitHub.

Appendix: source

Thrown at cli/command/image/build.go:233

	progBuff = dockerCli.Out()
	buildBuff = dockerCli.Out()
	if options.quiet {
		progBuff = bytes.NewBuffer(nil)
		buildBuff = bytes.NewBuffer(nil)
	}
	if options.imageIDFile != "" {
		// Avoid leaving a stale file if we eventually fail
		if err := os.Remove(options.imageIDFile); err != nil && !os.IsNotExist(err) {
			return fmt.Errorf("removing image ID file: %w", err)
		}
	}

	switch contextType {
	case build.ContextTypeStdin:
		// buildCtx is tar archive. if stdin was dockerfile then it is wrapped
		buildCtx, relDockerfile, err = build.GetContextFromReader(dockerCli.In(), options.dockerfileName)
		if err != nil {
			return fmt.Errorf("unable to prepare context from STDIN: %w", err)
		}
	case build.ContextTypeLocal:
		contextDir, relDockerfile, err = build.GetContextFromLocalDir(options.context, options.dockerfileName)
		if err != nil {
			return fmt.Errorf("unable to prepare context: %s", 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(options.dockerfileName)
			if err != nil {
				return fmt.Errorf("unable to open Dockerfile: %w", err)
			}
			defer dockerfileCtx.Close()
		}
	case build.ContextTypeGit:
		var tempDir string
		tempDir, relDockerfile, err = build.GetContextFromGitURL(options.context, options.dockerfileName)
		if err != nil {

View on GitHub (pinned to 4f84911bfe)