diff --git a/cli/mobycli/exec.go b/cli/mobycli/exec.go
index 8c4500050..15f875091 100644
--- a/cli/mobycli/exec.go
+++ b/cli/mobycli/exec.go
@@ -26,6 +26,7 @@ import (
 
 	"github.com/spf13/cobra"
 
+	"github.com/docker/compose-cli/cli/mobycli/resolvepath"
 	apicontext "github.com/docker/compose-cli/context"
 	"github.com/docker/compose-cli/context/store"
 	"github.com/docker/compose-cli/metrics"
@@ -60,7 +61,12 @@ func mustDelegateToMoby(ctxType string) bool {
 
 // Exec delegates to com.docker.cli if on moby context
 func Exec(root *cobra.Command) {
-	cmd := exec.Command(ComDockerCli, os.Args[1:]...)
+	execBinary, err := resolvepath.LookPath(ComDockerCli)
+	if err != nil {
+		fmt.Fprintln(os.Stderr, err)
+		os.Exit(1)
+	}
+	cmd := exec.Command(execBinary, os.Args[1:]...)
 	cmd.Stdin = os.Stdin
 	cmd.Stdout = os.Stdout
 	cmd.Stderr = os.Stderr
@@ -83,7 +89,7 @@ func Exec(root *cobra.Command) {
 		}
 	}()
 
-	err := cmd.Run()
+	err = cmd.Run()
 	childExit <- true
 	if err != nil {
 		metrics.Track(store.DefaultContextType, os.Args[1:], metrics.FailureStatus)
diff --git a/cli/mobycli/resolvepath/lp_unix.go b/cli/mobycli/resolvepath/lp_unix.go
new file mode 100644
index 000000000..44caa3648
--- /dev/null
+++ b/cli/mobycli/resolvepath/lp_unix.go
@@ -0,0 +1,28 @@
+// +build !windows
+
+/*
+   Copyright 2020 Docker Compose CLI authors
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+package resolvepath
+
+import (
+	"os/exec"
+)
+
+// LookPath simply delegate to os/exec.LookPath if not on windows
+func LookPath(file string) (string, error) {
+	return exec.LookPath(file)
+}
diff --git a/cli/mobycli/resolvepath/lp_windows.go b/cli/mobycli/resolvepath/lp_windows.go
new file mode 100644
index 000000000..65d9b5b89
--- /dev/null
+++ b/cli/mobycli/resolvepath/lp_windows.go
@@ -0,0 +1,126 @@
+/*
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+* Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+* Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+* Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package resolvepath
+
+import (
+	"errors"
+	"os"
+	"os/exec"
+	"path/filepath"
+	"strings"
+)
+
+// ErrNotFound is the error resulting if a path search failed to find an executable file.
+var ErrNotFound = errors.New("executable file not found in %PATH%")
+
+func chkStat(file string) error {
+	d, err := os.Stat(file)
+	if err != nil {
+		return err
+	}
+	if d.IsDir() {
+		return os.ErrPermission
+	}
+	return nil
+}
+
+func hasExt(file string) bool {
+	i := strings.LastIndex(file, ".")
+	if i < 0 {
+		return false
+	}
+	return strings.LastIndexAny(file, `:\/`) < i
+}
+
+func findExecutable(file string, exts []string) (string, error) {
+	if len(exts) == 0 {
+		return file, chkStat(file)
+	}
+	if hasExt(file) {
+		if chkStat(file) == nil {
+			return file, nil
+		}
+	}
+	for _, e := range exts {
+		if f := file + e; chkStat(f) == nil {
+			return f, nil
+		}
+	}
+	return "", os.ErrNotExist
+}
+
+// LookPath searches for an executable named file in the
+// directories named by the PATH environment variable.
+// If file contains a slash, it is tried directly and the PATH is not consulted.
+// LookPath also uses PATHEXT environment variable to match
+// a suitable candidate.
+// The result may be an absolute path or a path relative to the current directory.
+func LookPath(file string) (string, error) {
+	var exts []string
+	x := os.Getenv(`PATHEXT`)
+	if x != "" {
+		for _, e := range strings.Split(strings.ToLower(x), `;`) {
+			if e == "" {
+				continue
+			}
+			if e[0] != '.' {
+				e = "." + e
+			}
+			exts = append(exts, e)
+		}
+	} else {
+		exts = []string{".com", ".exe", ".bat", ".cmd"}
+	}
+
+	if strings.ContainsAny(file, `:\/`) {
+		if f, err := findExecutable(file, exts); err == nil {
+			return f, nil
+		} else {
+			return "", &exec.Error{file, err}
+		}
+	}
+	// See https://github.com/golang/go/issues/38736
+	// DO NOT lookup current folder
+	//if f, err := findExecutable(filepath.Join(".", file), exts); err == nil {
+	//	return f, nil
+	//}
+	path := os.Getenv("path")
+	for _, dir := range filepath.SplitList(path) {
+		// empty dir means dupicate semicolon in PATH, should not resolve files in current working dir...
+		if strings.TrimSpace(dir) == "" {
+			continue
+		}
+		if f, err := findExecutable(filepath.Join(dir, file), exts); err == nil {
+			return f, nil
+		}
+	}
+	return "", &exec.Error{file, ErrNotFound}
+}
diff --git a/scripts/validate/fileheader b/scripts/validate/fileheader
index b77b5a69f..8b503df36 100755
--- a/scripts/validate/fileheader
+++ b/scripts/validate/fileheader
@@ -24,4 +24,4 @@ fi
 
 BASEPATH="${1-}"
 
-ltag -t "${BASEPATH}scripts/validate/template" -excludes "validate testdata" --check -v
\ No newline at end of file
+ltag -t "${BASEPATH}scripts/validate/template" -excludes "validate testdata resolvepath" --check -v
\ No newline at end of file