peass-ng/PEASS-ng · error · ArgumentException

Invalid Subpath

Error message

Invalid Subpath

What it means

AlphaFS throws this ArgumentException when a subdirectory path passed to CreateSubdirectory (via CreateSubdirectoryCore) is not located underneath the current DirectoryInfo instance. The comparison is done on the long-path forms (LongFullName vs pathLp), case-insensitively, comparing only the parent-length prefix; a mismatch means the target is not a descendant of this directory.

Source

Thrown at winPEAS/winPEASexe/winPEAS/3rdParty/AlphaFS/Filesystem/DirectoryInfo Class/DirectoryInfo.CreateSubdirectoryCore.cs:52

      /// Any and all directories specified in path are created, unless some part of path is invalid.
      /// The path parameter specifies a directory path, not a file path.
      /// If the subdirectory already exists, this method does nothing.
      /// </remarks>
      /// <param name="path">The specified path. This cannot be a different disk volume or Universal Naming Convention (UNC) name.</param>
      /// <param name="templatePath">The path of the directory to use as a template when creating the new directory.</param>
      /// <param name="directorySecurity">The <see cref="DirectorySecurity"/> security to apply.</param>
      /// <param name="compress">When <c>true</c> compresses the directory using NTFS compression.</param>
      [SecurityCritical]
      private DirectoryInfo CreateSubdirectoryCore(string path, string templatePath, ObjectSecurity directorySecurity, bool compress)
      {
         var pathLp = Path.CombineCore(false, LongFullName, path);

         var templatePathLp = null == templatePath ? null : Path.GetExtendedLengthPathCore(Transaction, templatePath, PathFormat.RelativePath, GetFullPathOptions.TrimEnd | GetFullPathOptions.RemoveTrailingDirectorySeparator);


         if (string.Compare(LongFullName, 0, pathLp, 0, LongFullName.Length, StringComparison.OrdinalIgnoreCase) != 0)

            throw new ArgumentException(Resources.Invalid_Subpath, "path");


         return Directory.CreateDirectoryCore(false, Transaction, pathLp, templatePathLp, directorySecurity, compress, PathFormat.LongFullPath);
      }
   }
}

View on GitHub (pinned to 53fb989abc)

Solutions

  1. Ensure the target subdirectory path is relative and stays inside the DirectoryInfo instance (no leading '..' escapes, same drive).
  2. Compute the target by combining the directory's FullName with a relative name: dir.CreateSubdirectory(Path.Combine(dir.FullName, "child")).
  3. If an outside path is intended, use Directory.CreateDirectory(path) instead of DirectoryInfo.CreateSubdirectory.
  4. Normalize casing/drive-letter and remove relative segments before calling so the long-path prefix comparison succeeds.

Example fix

// before
drive.CreateSubdirectory("D:\\Temp\\out"); // ArgumentException: Invalid Subpath
// after
Directory.CreateDirectory("D:\\Temp\\out"); // target is outside the current directory
Defensive patterns

Strategy: validation

Validate before calling

static bool IsValidSubpath(DirectoryInfo dir, string subPath)
{
    if (string.IsNullOrWhiteSpace(subPath)) return false;
    string full = Path.GetFullPath(Path.Combine(dir.FullName, subPath));
    string parent = Path.GetFullPath(dir.FullName);
    return full.StartsWith(parent, StringComparison.OrdinalIgnoreCase)
        && !string.Equals(full, parent, StringComparison.OrdinalIgnoreCase);
}
// call only if IsValidSubpath(dir, subPath)

Type guard

static bool IsSubDirectory(DirectoryInfo dir, string candidate)
{
    var full = Path.GetFullPath(candidate);
    var baseP = Path.GetFullPath(dir.FullName);
    return full.StartsWith(baseP.TrimEnd(Path.DirectorySeparatorChar) + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase);
}

Try / catch

try { dir.CreateSubdirectory(subPath); }
catch (ArgumentException ex) when (ex.ParamName == "path")
{
    // not a subpath of dir: fall back to Directory.CreateDirectory
    Directory.CreateDirectory(subPath);
}

Prevention

When it happens

Trigger: Calling DirectoryInfo.CreateSubdirectory with a path such as an absolute path on another drive (e.g. dir on C:\Work creating D:\Temp), a sibling path like ..\Other, or any path whose extended/long-path normalized form (from Path.GetExtendedLengthPathCore) does not begin with the directory's LongFullName.

Common situations: Joining user-supplied or config-supplied output paths to a working directory that escapes it via '..' or a different drive letter; mixing short (8.3) names, relative paths, or UNC vs drive-letter forms so the normalized prefix no longer matches.

Related errors


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