peass-ng/PEASS-ng · error · FileReadOnlyException

ERROR_FILE_READ_ONLY

ERROR_FILE_READ_ONLY

Error message

({6000}) The file is read-only: [{destinationPathLp}]

What it means

During a move/copy AlphaFS hit the Win32 error ERROR_FILE_READ_ONLY (6000-mapped here): the destination file exists with the FILE_ATTRIBUTE_READONLY attribute. Mirroring MSDN behavior for .NET CopyFile, FileReadOnlyException (subclass of UnauthorizedAccessException) is thrown for the restart/move path unless a retry is in progress.

Source

Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Filesystem/File Class/File CopyMove/File.RestartMoveOrThrowException.cs:158

                  if (isMove && IsReadOnlyOrHidden(attrs.dwFileAttributes))
                  {
                     if (HasReplaceExisting(cma.MoveOptions))
                     {
                        // Reset attributes to Normal.
                        SetAttributesCore(cma.Transaction, isFolder, destinationPathLp, FileAttributes.Normal, PathFormat.LongFullPath);


                        restart = true;
                        break;
                     }


                     // MSDN: .NET 3.5+: UnauthorizedAccessException: destinationPath is read-only.
                     // MSDN: Win32 CopyFileXxx: This function fails with ERROR_ACCESS_DENIED if the destination file already exists
                     // and has the FILE_ATTRIBUTE_HIDDEN or FILE_ATTRIBUTE_READONLY attribute set.

                     if (!retry)
                        throw new FileReadOnlyException(destinationPathLp);
                  }
               }


               // MSDN: .NET 3.5+: An I/O error has occurred. 
               // File.Copy(): IOException: destinationPath exists and overwrite is false.
               // File.Move(): The destination file already exists or sourcePath was not found.

               if (!retry)
                  NativeError.ThrowException(lastError, isFolder, fileNameLp);

               break;
         }


         return restart;
      }
   }

View on GitHub (pinned to 53fb989abc)

Solutions

  1. Clear the read-only attribute on the destination before the operation: File.SetAttributes(dst, File.GetAttributes(dst) & ~FileAttributes.ReadOnly).
  2. Delete the existing read-only destination file first, then perform the move/copy.
  3. Check File.Exists(dst) and its attributes beforehand and skip or archive the existing file instead of overwriting.

Example fix

// before
File.Move(src, dst, MoveOptions.Overwrite); // FileReadOnlyException if dst is read-only
// after
if (File.Exists(dst))
    File.SetAttributes(dst, File.GetAttributes(dst) & ~FileAttributes.ReadOnly);
File.Move(src, dst, MoveOptions.Overwrite);
Defensive patterns

Strategy: validation

Validate before calling

static void ClearReadOnly(string destinationPath)
{
    if (File.Exists(destinationPath))
    {
        var attrs = File.GetAttributes(destinationPath);
        if ((attrs & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
            File.SetAttributes(destinationPath, attrs & ~FileAttributes.ReadOnly);
    }
}
// call ClearReadOnly(dst) before File.Move/CopyMove with overwrite

Type guard

static bool IsDestinationReadOnly(string dst) =>
    File.Exists(dst) && File.GetAttributes(dst).HasFlag(FileAttributes.ReadOnly);

Try / catch

try { File.Move(src, dst, MoveOptions.Overwrite); }
catch (UnauthorizedAccessException)
{
    var attrs = File.GetAttributes(dst);
    File.SetAttributes(dst, attrs & ~FileAttributes.ReadOnly);
    File.Move(src, dst, MoveOptions.Overwrite);
}

Prevention

When it happens

Trigger: File.Move/File.CopyMove where the destination file already exists and has the read-only attribute set; Windows refuses to overwrite a read-only destination (Win32 CopyFileXxx also fails with ERROR_ACCESS_DENIED for hidden/read-only destinations).

Common situations: Overwriting files checked out of source control as read-only; copying over files from read-only media or templates; re-running a deployment that previously produced a write-protected output file.

Related errors


AI-assisted analysis of peass-ng/PEASS-ng@53fb989abc (2026-09-02). Data as JSON: /api/errors/281eddb9d556597e. Report an issue: GitHub.