diff --git a/pkg/minikube/cluster/filesync.go b/pkg/minikube/cluster/filesync.go
index 6bf4559335..e5606a2c94 100644
--- a/pkg/minikube/cluster/filesync.go
+++ b/pkg/minikube/cluster/filesync.go
@@ -19,6 +19,7 @@ package cluster
 import (
 	"fmt"
 	"os"
+	"os/exec"
 	"path"
 	"path/filepath"
 
@@ -37,6 +38,20 @@ func syncLocalAssets(cr command.Runner) error {
 		return err
 	}
 
+	dirs := map[string]bool{}
+	for _, f := range fs {
+		dirs[f.GetTargetDir()] = true
+	}
+
+	args := []string{"mkdir", "-p"}
+	for k, _ := range dirs {
+		args = append(args, k)
+	}
+	cmd := exec.Command("sudo", args...)
+	if _, err := cr.RunCmd(cmd); err != nil {
+		return err
+	}
+
 	for _, f := range fs {
 		err := cr.Copy(f)
 		if err != nil {
@@ -79,6 +94,9 @@ func assetsFromDir(localRoot string, destRoot string, flatten bool) ([]assets.Co
 			return err
 		}
 
+		// On Windows, rel will be separated by \, which is not correct inside the VM
+		rel = filepath.ToSlash(rel)
+
 		// The conversion will strip the leading 0 if present, so add it back if necessary
 		ps := fmt.Sprintf("%o", fi.Mode().Perm())
 		if len(ps) == 3 {
diff --git a/test/integration/functional_test.go b/test/integration/functional_test.go
index df85356bb5..c3a83abe6e 100644
--- a/test/integration/functional_test.go
+++ b/test/integration/functional_test.go
@@ -56,7 +56,13 @@ func TestFunctional(t *testing.T) {
 
 	profile := UniqueProfileName("functional")
 	ctx, cancel := context.WithTimeout(context.Background(), 40*time.Minute)
-	defer CleanupWithLogs(t, profile, cancel)
+	defer func() {
+		p := localSyncTestPath()
+		if err := os.Remove(p); err != nil {
+			t.Logf("unable to remove %s: %v", p, err)
+		}
+		CleanupWithLogs(t, profile, cancel)
+	}()
 
 	// Serial tests
 	t.Run("serial", func(t *testing.T) {
@@ -626,11 +632,21 @@ func validateMySQL(ctx context.Context, t *testing.T, profile string) {
 	}
 }
 
+// vmSyncTestPath is where the test file will be synced into the VM
+func vmSyncTestPath() string {
+	return fmt.Sprintf("/etc/test/nested/copy/%d/hosts", os.Getpid())
+}
+
+// localSyncTestPath is where the test file will be synced into the VM
+func localSyncTestPath() string {
+	return filepath.Join(localpath.MiniPath(), "/files", vmSyncTestPath())
+}
+
 // Copy extra file into minikube home folder for file sync test
 func setupFileSync(ctx context.Context, t *testing.T, profile string) {
-	// 1. copy random file to MINIKUBE_HOME/files/etc
-	f := filepath.Join(localpath.MiniPath(), "/files/etc/sync.test")
-	err := copy.Copy("./testdata/sync.test", f)
+	p := localSyncTestPath()
+	t.Logf("local sync path: %s", p)
+	err := copy.Copy("./testdata/sync.test", p)
 	if err != nil {
 		t.Fatalf("copy: %v", err)
 	}
@@ -641,18 +657,22 @@ func validateFileSync(ctx context.Context, t *testing.T, profile string) {
 	if NoneDriver() {
 		t.Skipf("skipping: ssh unsupported by none")
 	}
-	// check file existence
-	rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "ssh", "cat /etc/sync.test"))
+
+	vp := vmSyncTestPath()
+	t.Logf("Checking for existence of %s within VM", vp)
+	rr, err := Run(t, exec.CommandContext(ctx, Target(), "-p", profile, "ssh", fmt.Sprintf("cat %s", vp)))
 	if err != nil {
 		t.Errorf("%s failed: %v", rr.Args, err)
 	}
+	got := rr.Stdout.String()
+	t.Logf("file sync test content: %s", got)
 
 	expected, err := ioutil.ReadFile("./testdata/sync.test")
 	if err != nil {
 		t.Errorf("test file not found: %v", err)
 	}
 
-	if diff := cmp.Diff(string(expected), rr.Stdout.String()); diff != "" {
+	if diff := cmp.Diff(string(expected), got); diff != "" {
 		t.Errorf("/etc/sync.test content mismatch (-want +got):\n%s", diff)
 	}
 }