docker/cli · error

invalid output path: directory

Error message

invalid output path: directory %q does not exist

What it means

Returned by ValidateOutputPath when the parent directory of a requested output path does not exist on disk. ValidateOutputPath is the validator used by the `docker cp` command to sanity-check the local destination before copying a file out of a container (cli/command/utils.go:62). It takes filepath.Dir of the cleaned path and runs os.Stat on it; if that reports IsNotExist, the copy is rejected up front rather than failing mid-transfer.

Solutions

  1. Create the parent directory first: mkdir -p <dir> before running docker cp.
  2. Verify the destination spelling and that you are pointing at a real path with ls <dir>.
  3. If the dir was supposed to exist, check that the volume/mount backing it is attached.

Example fix

// before
docker cp mycontainer:/data/out.tar /opt/exports/notcreated/out.tar
// after (create the parent first)
mkdir -p /opt/exports/notcreated && docker cp mycontainer:/data/out.tar /opt/exports/notcreated/out.tar
Defensive patterns

Strategy: validation

Validate before calling

// Verify the parent dir exists before calling ValidateOutputPath.
func ensureOutputPath(path string) error {
    dir := filepath.Dir(filepath.Clean(path))
    if dir != "" && dir != "." {
        if _, err := os.Stat(dir); os.IsNotExist(err) {
            if err := os.MkdirAll(dir, 0o755); err != nil {
                return err
            }
        }
    }
    return nil
}
// usage:
// if err := ensureOutputPath(dest); err != nil { return err }
// if err := command.ValidateOutputPath(dest); err != nil { return err }

Prevention

When it happens

Trigger: Calling ValidateOutputPath("/nonexistent/dir/file.tar") (or any docker cp whose destination's parent dir is missing). The check at utils.go:64-66 triggers when dir != "." and os.Stat(dir) returns an IsNotExist error.

Common situations: Typo in a destination path; passing a path under a directory you forgot to create; an output dir that lives inside a mount that isn't mounted yet; CI runners where the working directory layout differs from local.

Related errors


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

Appendix: source

Thrown at cli/command/utils.go:66

			// "label != some-value" conflicts with "label = some-value"
			if pruneFilters["label"][v] {
				continue
			}
			pruneFilters.Add(k, v)
		default:
			pruneFilters.Add(k, v)
		}
	}

	return pruneFilters
}

// ValidateOutputPath validates the output paths of the "docker cp" command.
func ValidateOutputPath(path string) error {
	dir := filepath.Dir(filepath.Clean(path))
	if dir != "" && dir != "." {
		if _, err := os.Stat(dir); os.IsNotExist(err) {
			return fmt.Errorf("invalid output path: directory %q does not exist", dir)
		}
	}
	// check whether `path` points to a regular file
	// (if the path exists and doesn't point to a directory)
	if fileInfo, err := os.Stat(path); !os.IsNotExist(err) {
		if err != nil {
			return err
		}

		if fileInfo.Mode().IsDir() || fileInfo.Mode().IsRegular() {
			return nil
		}

		if err := ValidateOutputPathFileMode(fileInfo.Mode()); err != nil {
			return fmt.Errorf("invalid output path: %q must be a directory or a regular file: %w", path, err)
		}
	}
	return nil

View on GitHub (pinned to 4f84911bfe)