diff --git a/sftpd/internal_test.go b/sftpd/internal_test.go
index 942c97f1..5e4a9e62 100644
--- a/sftpd/internal_test.go
+++ b/sftpd/internal_test.go
@@ -342,6 +342,21 @@ func TestWithInvalidHome(t *testing.T) {
 	assert.Error(t, err)
 }
 
+func TestResolveWithRootDir(t *testing.T) {
+	u := dataprovider.User{}
+	if runtime.GOOS == osWindows {
+		u.HomeDir = "C:\\"
+	} else {
+		u.HomeDir = "/"
+	}
+	fs, err := u.GetFilesystem("")
+	assert.NoError(t, err)
+	rel, err := filepath.Rel(u.HomeDir, os.TempDir())
+	assert.NoError(t, err)
+	p, err := fs.ResolvePath(rel)
+	assert.NoError(t, err, "path %v", p)
+}
+
 func TestSFTPGetUsedQuota(t *testing.T) {
 	u := dataprovider.User{}
 	u.HomeDir = "home_rel_path"
diff --git a/vfs/osfs.go b/vfs/osfs.go
index 7ed75626..0d548cd1 100644
--- a/vfs/osfs.go
+++ b/vfs/osfs.go
@@ -359,7 +359,13 @@ func (fs *OsFs) isSubDir(sub string) error {
 		err = fmt.Errorf("path %#v is not inside %#v", sub, parent)
 		return err
 	}
-	if !strings.HasPrefix(sub, parent+string(os.PathSeparator)) {
+	separator := string(os.PathSeparator)
+	if parent == filepath.Dir(parent) {
+		// parent is the root dir, on Windows we can have C:\, D:\ and so on here
+		// so we still need the prefix check
+		separator = ""
+	}
+	if !strings.HasPrefix(sub, parent+separator) {
 		err = fmt.Errorf("path %#v is not inside %#v", sub, parent)
 		return err
 	}