Why os.Rename Fails Across Devices in Go and How to Fix It

This article explains why Go's os.Rename throws an "invalid cross-device link" error when moving files between different file systems and shows how to replace it with io.Copy for reliable cross‑device file transfers, including code examples and related filesystem concepts.

Ops Development & AI Practice
Ops Development & AI Practice
Ops Development & AI Practice
Why os.Rename Fails Across Devices in Go and How to Fix It

Error Analysis

The os.Rename function renames a file or directory by internally invoking the renameat2 system call, which only succeeds when the source and destination reside on the same filesystem. If they are on different filesystems, the call fails with the invalid cross-device link error.

Solution

To move files across devices, replace os.Rename with io.Copy. The io.Copy function copies the byte stream from the source file to the destination file without any filesystem restrictions.

Code Example: Cross‑Device File Move

func moveFile(src, dst string) error {
    // Open source file
    srcFile, err := os.Open(src)
    if err != nil {
        return err
    }
    defer srcFile.Close()

    // Create destination file
    dstFile, err := os.Create(dst)
    if err != nil {
        return err
    }
    defer dstFile.Close()

    // Copy file contents
    _, err = io.Copy(dstFile, srcFile)
    if err != nil {
        return err
    }

    // Delete source file
    err = os.Remove(src)
    if err != nil {
        return err
    }

    return nil
}

Additional Knowledge

Filesystem : A method for organizing and managing storage space, with each type having its own features and limitations such as supported file types, maximum file size, and permission controls.

Cross‑Device Links : Links that point to files or directories on different filesystems. On Linux, the ln command can create such links.

io.Copy : A standard Go library function that copies data from one stream to another, useful for files, network connections, pipes, etc.

Clearing a File : The os.Truncate function can shrink a file to a specified length; setting the length to 0 effectively empties the file.

Helper Function: Clear File

func clearFile(f *os.File) error {
    // Truncate file size to 0
    err := f.Truncate(0)
    if err != nil {
        return err
    }

    // Reset file pointer to the beginning
    _, err = f.Seek(0, io.SeekStart)
    if err != nil {
        return err
    }

    return nil
}

Summary

os.Rename

cannot be used for cross‑device file moves; it raises the invalid cross-device link error.

Use io.Copy instead of os.Rename to achieve reliable cross‑device file transfers.

Understanding filesystems, cross‑device links, and the io.Copy function helps developers handle file operations more effectively.

Further Reading

Linux Filesystem Documentation: https://www.kernel.org/doc/html/latest/filesystems/

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Gocross-devicefile-handlingio.Copyos.Rename
Ops Development & AI Practice
Written by

Ops Development & AI Practice

DevSecOps engineer sharing experiences and insights on AI, Web3, and Claude code development. Aims to help solve technical challenges, improve development efficiency, and grow through community interaction. Feel free to comment and discuss.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.