diff --git a/src/os/file_unix.go b/src/os/file_unix.go
index 86271d53e897d1b6bc4618419340a64c0bbe064e..f790b6e910dd75ecdf15278a9b29bbd4131ed5ca 100644
--- a/src/os/file_unix.go
+++ b/src/os/file_unix.go
@@ -20,11 +20,20 @@ func fixLongPath(path string) string {
 func rename(oldname, newname string) error {
 	fi, err := Lstat(newname)
 	if err == nil && fi.IsDir() {
+		// if we cannot stat oldname we should
+		// return that error in favor of EEXIST
+		fi, err = Lstat(oldname)
+		if err != nil {
+			if pErr, ok := err.(*PathError); ok {
+				err = pErr.Err
+			}
+			return &LinkError{"rename", oldname, newname, err}
+		}
 		return &LinkError{"rename", oldname, newname, syscall.EEXIST}
 	}
-	e := syscall.Rename(oldname, newname)
-	if e != nil {
-		return &LinkError{"rename", oldname, newname, e}
+	err = syscall.Rename(oldname, newname)
+	if err != nil {
+		return &LinkError{"rename", oldname, newname, err}
 	}
 	return nil
 }
diff --git a/src/os/os_test.go b/src/os/os_test.go
index 8e2cd14ddf1b48c29c6b94c3fbf01a227971bcfb..22777aef9f7723c85399955c91c68230a4cda2ab 100644
--- a/src/os/os_test.go
+++ b/src/os/os_test.go
@@ -886,6 +886,18 @@ func TestRenameFailed(t *testing.T) {
 	}
 }
 
+func TestRenameNotExisting(t *testing.T) {
+	defer chtmpdir(t)()
+	from, to := "doesnt-exist", "dest"
+
+	Mkdir(to, 0777)
+	defer Remove(to)
+
+	if err := Rename(from, to); !IsNotExist(err) {
+		t.Errorf("Rename(%q, %q) = %v; want an IsNotExist error", from, to, err)
+	}
+}
+
 func TestRenameToDirFailed(t *testing.T) {
 	defer chtmpdir(t)()
 	from, to := "renamefrom", "renameto"