Share via

Microsoft Graph PATCH nested folder creation causes URL double-encoding bug on parent folders

DSR Automation 50 Reputation points
2026-05-29T12:35:47.0133333+00:00

Hi. Im using graph api to create folders (either single or nested) and get the leaf's id. Otherwise i just fetch its id. The problem im facing is some weird behaviour in some cases. For example, im going to create a folder with the following api and body.

Patch https://graph.microsoft.com/v1.0/sites/drives/root:/@%23%23%23%23%23%23%23%28%28%28%28%28%28%28_%29%29%29%29IITEIDHDB%25%25@%5E%23&&&@%7B%5D%5B%5D%5B%5D%5B%5B%5B@@@@@@@@@@@@@@@%23%23%23%23%23___%21@%21@%23%23%23%23%23%23%23%21%21%21%21%21%21%21%21%21%21%21Deddeeww=%60%60%60%60ssssjejejejenednjejejee%2%2Fsarf_sarfaraz%2Fsarf2?$select=id,name,webUrl 

Body


{
    "folder": {},
    "@microsoft.graph.conflictBehavior": "fail"
}

The folder that is created is this

@#%23%23%23%23%23%23((((((())))IITEIDHDB%25%25@^%23&&&@{][][][[[@@@@@@@@@@@@@@@%23%23%23%23%23__!@!@%23%23%23%23%23%23%23!!!!!!!!!!!Deddeeww=````ssssjejejejenednjejejee

The top folder is created incorrectly because the backend double-encodes the path. In Screenshot 1, you can see the returned webUrl contains .../Shared%20Documents/@%23%2523%2523... instead of evaluating the characters properly.

This results in subsequent GET requests failing with a 404 Not Found on the same path (Screenshot 2). However, if I attempt to execute the exact same PATCH request a second time, the API returns a 409 Conflict, even though the GET request says it does not exist.

When I try to create the folder in parts, it works fine. When I make an initial API call just for the root path:

Patch https://graph.microsoft.com/v1.0/sites/5B%5B@@@@@@@@@@@@@@@%23%23%23%23%23___%21@%21@%23%23%23%23%23%23%23%21%21%21%21%21%21%21%21%21%21%21Deddeeww=%60%60%60%60ssssjejejejenednjejejee?$select=id,name,webUrl

The folder is created with the correct name. Then, I make a subsequent call on the original deep URL to populate the nested folders, and it successfully resolves.

As a result, two completely distinct folder items are generated on the backend for what should be the same path. These are the 2 folders that were created, the older is the one created with single url. The newer is the one where I break it into 2 url calls.

I can't make individual calls for folders due to performance constraints. It looks like the Graph API deep-path parsing layer is skipping the URL-decoding step for intermediate segments (for example, %23 is literally being created as %23 instead of #). Please look into this routing/decoding bug.

Microsoft 365 and Office | SharePoint | Development
0 comments No comments

2 answers

Sort by: Most helpful
  1. Jayden-P 22,475 Reputation points Microsoft External Staff Moderator
    2026-05-29T14:06:05.6266667+00:00

    Please note that we're not Microsoft support, this is a user-to-user support forum. Moderators have no backend access and cannot directly intervene in Microsoft products. We provide only technical guidance and best-practice recommendations based on reported issues.

    Please note that our forum is a public platform, and we will modify your question to hide your personal information in the description. Kindly ensure that you hide any personal or organizational information the next time you post an error or other details to protect personal data.

    Hi @DSR Automation First, may I ask which endpoint do you use to create the folder? I found this endpoint, can you try to run this:

    POST /sites/{site-id}/drive/items/{parent-item-id}/children

    {
      "name": "######",
      "folder": { },
      "@microsoft.graph.conflictBehavior": "rename"
    }
    

    This will create a folder with name "#####". The web URL will be like this ".../Documents/%23%23%23%23".

    If you must keep deep-path creation, create the immediate parent first (one short PATCH), then do the deep PATCH for the remaining levels.

    Additionally, you can consider using SharePoint REST API using the ResourcePath / decodedUrl approach:

    POST /_api/web/folders/AddUsingPath(decodedurl='...') or GetFolderByServerRelativePath(decodedurl=...).

    Ref: https://learn.microsoft.com/en-us/sharepoint/dev/solution-guidance/supporting-and-in-file-and-folder-with-the-resourcepath-api#create-folder

    These APIs are explicitly designed to work with # and % when you pass a decoded path string.

    If you want to investigate this further, please contact Microsoft Graph support via Microsoft Graph | Support

    As a forum moderator, I do not have access to intervene in Microsoft products feature and functionality. Thanks for your understanding.


    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Was this answer helpful?

    0 comments No comments

  2. AI answer

    2026-05-29T12:36:54.0933333+00:00

    The behavior is caused by how Microsoft Graph and OneDrive/SharePoint handle URL path encoding and reserved characters, not by a missing decoding step.

    Key points from the documented behavior:

    1. Paths must follow RFC 3986 and be encoded segment-by-segment
      • Microsoft Graph expects URLs that conform to RFC 3986.
      • Only characters in the pchar set are allowed unencoded in the path. Characters such as # and space must be percent-encoded.
      • Graph uses standard percent encoding: for example, " "%20, "#"%23.
      • The documentation explicitly warns that the entire URL must not be encoded in one call; each path segment must be encoded correctly when building the URL. Otherwise, the URL becomes ambiguous and can lead to incorrect interpretation of the path.
    2. OneDrive/SharePoint reserved characters and limitations
      • OneDrive and OneDrive for Business have reserved characters that cannot appear in file or folder names: /, \\, *, <, >, ?, :, |, and in OneDrive for Business also # and %.
      • Folder names also cannot end with a period, and OneDrive for Business names cannot begin with ~.
      • Because # and % are reserved in OneDrive for Business, using them (even via percent-encoding) in folder names can lead to special handling and ambiguity.
    3. Impact on deep path creation
      • When a deep path is sent where intermediate segments contain characters like # and % that are already percent-encoded, the server treats those characters as literal parts of the name.
      • If the client additionally encodes the whole path or re-encodes already encoded segments, the server can end up storing names that contain the literal %23 or %25 sequences. This explains the webUrl values that show @%23%2523...: the % in %23 has itself been encoded to %25, so the stored name includes %23 instead of #.
      • Because the stored item name no longer matches the intended logical path, subsequent GETs using a differently encoded path can return 404, while a second PATCH with the same (double-encoded) path returns 409 because an item with that exact literal name already exists.
    4. Why creating the root folder first works
      • When the root folder is created in a separate call, the path for that segment is resolved and stored once, with the encoding applied consistently for that segment only.
      • Subsequent calls that use the same encoding for deeper segments then resolve correctly, so the nested structure is created as expected.
    5. Recommended approach / mitigation
      • Ensure that each path segment is encoded exactly once according to RFC 3986 and that the client does not re-encode already encoded characters when building the full URL. In particular:
        • Do not encode the entire URL string in one operation.
        • Encode only characters that are not allowed in pchar (for example, #%23).
      • Avoid using OneDrive/SharePoint reserved characters (#, %, /, \\, *, <, >, ?, :, |) in folder names where possible, because they are explicitly called out as unsupported or reserved and can cause ambiguous behavior.
      • For SharePoint-specific scenarios that must support # and % in file and folder names, use the newer ResourcePath-based APIs in SharePoint (for example, GetFileByServerRelativePath, GetListUsingPath, SPFileCollection.GetByPath, etc.), which are designed to handle # and % without ambiguity. These APIs return and accept SPResourcePath/System.Uri values with unambiguous encoding.

    Given the documented constraints, the safest pattern is:

    1. Construct the Graph path by encoding each folder name once, ensuring no double-encoding of % or #.
    2. Avoid reserved characters in names where possible; if they must be used in SharePoint, prefer the ResourcePath-based CSOM/REST APIs instead of relying on deep path creation via Graph.

    References:

    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.