Skip to content

fs.copyFile fails if source is readonly and target is a CIFS volume #60557

Description

@johaven

Version

v22.21.1

Platform

Linux a7f6d3be6434 5.15.158-2-pve #1 SMP PVE 5.15.158-2 (2024-07-26T13:11Z) x86_64 Linux

Docker: Alpine release 3.22.2

Subsystem

fs

What steps will reproduce the bug?

Hi,

Copying sample.docx fails with EPERM because the source is read-only and the destination is a CIFS share.

Probably related to:

#37284
libuv/libuv#3117
#44261

How often does it reproduce? Is there a required condition?

100% reproducible

What is the expected behavior? Why is that the expected behavior?

/mnt/smb is a CIFS-mounted volume.
sample.docx is a file with read-only permissions for the user running the below code.

Code

import {copyFile} from "fs/promises";

const src = "./sample.docx";
const dest = "/mnt/smb/sample.docx";

await copyFile(src, dest);

console.log("File copied successfully");

The fs.copyFile should be able to succeed in copying the file as long as the destination folder is writable.

What do you see instead?

Error

node:internal/modules/run_main:123
    triggerUncaughtException(
    ^
[Error: EPERM: operation not permitted, copyfile './sample.docx' -> '/mnt/smb/sample.docx'] {
  errno: -1,
  code: 'EPERM',
  syscall: 'copyfile',
  path: './sample.docx',
  dest: '/mnt/smb/sample.docx'
}

Additional information

Works with no error

cp ./sample.docx /mnt/smb/sample.docx

Activity

  1. ish1416 commented on Nov 7, 2025

    @ish1416

    @johaven I can reproduce this issue. The problem occurs because fs.copyFile uses uv_fs_copyfile() which tries to preserve file permissions, but CIFS doesn't support setting read-only permissions on the destination.

    The solution is to implement a fallback mechanism when uv_fs_copyfile() fails with EPERM on CIFS volumes - fall back to manual read/write operations that don't attempt to preserve the read-only permission.

    I'd like to work on this fix. Should I proceed with implementing the fallback approach?

  2. added
    libuvIssues and PRs related to the libuv dependency or the uv binding.
    on Dec 3, 2025
  3. juanarbol commented on Dec 3, 2025

    @juanarbol
    Member

    I'd like to work on this fix. Should I proceed with implementing the fallback approach?

    Nice! Let me do a humble ping to @nodejs/libuv

  4. github-actions commented on Jul 2, 2026

    @github-actions
    Contributor

    This issue has been marked as stale due to 210 days of inactivity.
    It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

  5. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Jul 2, 2026
  6. johaven commented on Jul 2, 2026

    @johaven
    Author

    Up

  7. removed
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on Jul 3, 2026
  8. bnoordhuis commented on Sep 3, 2026

    @bnoordhuis
    Member

    See libuv/libuv@0f696da - we already handle EPERM from the final fchmod, and have for a while. Can you get me an strace log of the actually failing system call?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    libuvIssues and PRs related to the libuv dependency or the uv binding.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions