docker/cli ยท error
context must be a directory
Error message
context must be a directory
What it means
Raised by validateContextDir during `docker plugin create` when the given plugin context path exists (Lstat succeeds) but is not a directory. A plugin build context must be a directory containing config.json and a rootfs; a file, symlink to a file, or tarball path is rejected.
Source
Thrown at cli/command/plugin/create.go:55
err = json.NewDecoder(dt).Decode(&m)
_ = dt.Close()
return err
}
// validateContextDir validates the given dir and returns its absolute path on success.
func validateContextDir(contextDir string) (string, error) {
absContextDir, err := filepath.Abs(contextDir)
if err != nil {
return "", err
}
stat, err := os.Lstat(absContextDir)
if err != nil {
return "", err
}
if !stat.IsDir() {
return "", errors.New("context must be a directory")
}
return absContextDir, nil
}
type pluginCreateOptions struct {
repoName string
context string
compress bool
}
func newCreateCommand(dockerCLI command.Cli) *cobra.Command {
options := pluginCreateOptions{}
cmd := &cobra.Command{
Use: "create [OPTIONS] PLUGIN PLUGIN-DATA-DIR",
Short: "Create a plugin from a rootfs and configuration. Plugin data directory must contain config.json and rootfs directory.",
Args: cli.RequiresMinArgs(2),View on GitHub (pinned to e9452d6e78)
Solutions
- Pass the directory containing config.json and rootfs/: `docker plugin create myplugin ./plugin-dir`
- If you have a tarball, extract it first (tar -xf plugin.tar.gz -C plugin-dir) and pass the directory
- Check the path with `ls -ld <path>` to confirm it is a directory
Example fix
# before docker plugin create myplugin ./plugin.tar.gz # after mkdir plugin-dir && tar -xzf plugin.tar.gz -C plugin-dir docker plugin create myplugin ./plugin-dir
When it happens
Trigger: `docker plugin create myplugin ./path` where ./path is a regular file (e.g. a .tar.gz or the config.json itself) or a symlink whose Lstat target is not a directory.
Common situations: Pointing the command at a plugin tarball instead of the unpacked directory; passing config.json directly instead of its parent directory; typo resolving to a file.
Related errors
- the plugin must be disabled before upgrading
- plugin upgrade has been cancelled
- every ip-range or gateway must have a corresponding subnet
- multiple overlapping subnet configuration is not supported
- network prune has been cancelled
AI-assisted analysis of docker/cli@e9452d6e78 (2026-08-01).
Data as JSON: /data/errors/7e261856d7c9947a.json.
Report an issue: GitHub.