Windows AppContainer: How to verify profile existence before creation and resolve GetAppContainerFolderPath 0x80070002?

WST Developer 0 Reputation points
2026-11-04T04:56:39.58+00:00

Hello Microsoft Community,

I'm developing a Windows 11 application that requires AppContainer isolation. I need guidance on the officially supported methods for verifying an AppContainer profile before creation and performing a safe rollback if necessary.

Environment

  • Windows 11, 64-bit

Windows PowerShell 5.1

Local standard user account (non-administrator)

Native Windows Userenv APIs called through C# P/Invoke

What I have tested

DeriveAppContainerSidFromAppContainerName returned S_OK and successfully derived an AppContainer SID from a fixed name.

A read-only check of the target SID's AppContainer Mapping key under the current user's HKCU did not find a matching entry.

I called GetAppContainerFolderPath once with the derived SID string. The API returned:

HRESULT: 0x80070002 (ERROR_FILE_NOT_FOUND)

  Returned path pointer: `NULL`
  
     No managed exception
     
        No path was returned
        
        I have **not** called `CreateAppContainerProfile` or `DeleteAppContainerProfile`.
        

I understand that successfully deriving a SID does not prove that an AppContainer profile exists, and that a missing Registry mapping or failed folder-path query does not necessarily prove that the profile is absent.

My questions

1. Profile existence verification

Is there an officially supported, non-mutating Windows API that allows a non-elevated process to determine whether a specific per-user AppContainer profile already exists?

How can I distinguish an existing profile, an absent profile, an incomplete profile, and an inaccessible profile?

Would NetworkIsolationEnumAppContainers provide reliable evidence for this purpose, or is its scope different from Userenv-managed profiles?

2. GetAppContainerFolderPath error

What documented conditions can cause GetAppContainerFolderPath to return 0x80070002 when supplied with a valid derived AppContainer SID?

Can this indicate a missing profile registration, incomplete profile storage, or another missing dependency?

3. Safe creation and rollback

If I later create a profile using CreateAppContainerProfile, what is the recommended method to verify successful provisioning and identify the resources created?

If creation succeeds but subsequent SID or resource verification fails, how should the state be handled safely?

Before calling DeleteAppContainerProfile, how can I verify that the profile was created by my operation, is not being used, and can be removed without affecting pre-existing resources?

I would appreciate links to official Microsoft documentation and clarification of any guarantees that the public APIs do not provide.

Thank you for your guidance.Hello Microsoft Community,

I'm developing a Windows 11 application that requires AppContainer isolation. I need guidance on the officially supported methods for verifying an AppContainer profile before creation and performing a safe rollback if necessary.

Environment

Windows 11, 64-bit

Windows PowerShell 5.1

Local standard user account (non-administrator)

Native Windows Userenv APIs called through C# P/Invoke

What I have tested

DeriveAppContainerSidFromAppContainerName returned S_OK and successfully derived an AppContainer SID from a fixed name.

A read-only check of the target SID's AppContainer Mapping key under the current user's HKCU did not find a matching entry.

I called GetAppContainerFolderPath once with the derived SID string. The API returned:

HRESULT: 0x80070002 (ERROR_FILE_NOT_FOUND)

  Returned path pointer: `NULL`
  
     No managed exception
     
        No path was returned
        
        I have **not** called `CreateAppContainerProfile` or `DeleteAppContainerProfile`.
        

I understand that successfully deriving a SID does not prove that an AppContainer profile exists, and that a missing Registry mapping or failed folder-path query does not necessarily prove that the profile is absent.

My questions

1. Profile existence verification

Is there an officially supported, non-mutating Windows API that allows a non-elevated process to determine whether a specific per-user AppContainer profile already exists?

How can I distinguish an existing profile, an absent profile, an incomplete profile, and an inaccessible profile?

Would NetworkIsolationEnumAppContainers provide reliable evidence for this purpose, or is its scope different from Userenv-managed profiles?

2. GetAppContainerFolderPath error

What documented conditions can cause GetAppContainerFolderPath to return 0x80070002 when supplied with a valid derived AppContainer SID?

Can this indicate a missing profile registration, incomplete profile storage, or another missing dependency?

3. Safe creation and rollback

If I later create a profile using CreateAppContainerProfile, what is the recommended method to verify successful provisioning and identify the resources created?

If creation succeeds but subsequent SID or resource verification fails, how should the state be handled safely?

Before calling DeleteAppContainerProfile, how can I verify that the profile was created by my operation, is not being used, and can be removed without affecting pre-existing resources?

I would appreciate links to official Microsoft documentation and clarification of any guarantees that the public APIs do not provide.

Thank you for your guidance.

Windows development | Windows API - Win32
0 comments No comments

2 answers

Sort by: Newest
  1. Harry Nguyen (WICLOUD CORPORATION) 610 Reputation points Microsoft External Staff Moderator
    2026-11-04T07:32:23.4733333+00:00

    Hi @WST Developer , 

    1. Checking whether a profile exists 

    There's no documented API that just checks whether a profile exists without changing anything. The documented approach is to call CreateAppContainerProfile and check the result. If it returns HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS), get the SID from the name, as shown in Launch an AppContainer. 

    DeriveAppContainerSidFromAppContainerName only documents S_OK and E_INVALIDARG, with no "profile not found" case, so getting S_OK doesn't confirm the profile exists. 

    You can use NetworkIsolationEnumAppContainers as extra evidence by filtering on your user SID and AppContainer SID. A match is a good sign, but no match doesn't prove the profile is missing. Remember to free the result with NetworkIsolationFreeAppContainers. 

    The HKCU mapping key isn't documented, so I wouldn't rely on it. 

    2. GetAppContainerFolderPath returning 0x80070002 

    ERROR_FILE_NOT_FOUND isn't documented for GetAppContainerFolderPath. Since you haven't called CreateAppContainerProfile for this name yet, a likely reason is that the profile simply doesn't exist, though the docs don't confirm this. Please also check whether the calling thread was impersonating, because that changes which user context the API uses. 

    A quick way to confirm: 

    1. Create a test profile. 
    2. Convert the returned SID with ConvertSidToStringSidW. 
    3. Call GetAppContainerFolderPath with that string. If it works, that supports the missing-profile explanation. 
    4. Delete the test profile afterwards. 

    3. Safe creation and rollback 

    Only treat the profile as yours when CreateAppContainerProfile returns S_OK. If it returns ERROR_ALREADY_EXISTS or any other error, don't mark it as owned and don't delete it during rollback. After S_OK, you can compare the returned SID with the derived SID and call GetAppContainerFolderPath as a check, but there's no documented API that lists every resource the profile creates. If these checks fail, roll back the profile as described below. 

    For cleanup, follow the DeleteAppContainerProfile docs: make sure your launched processes have exited and your handles are closed, call it from outside the container under the same user, and retry if it fails. There's no documented way to check whether other processes are using the profile, so you'll need to track the processes your own app launched. 

    If MSIX is an option, Windows manages the profile for you when the package is registered and unregistered. See AppContainer for legacy apps. 

    If you found this helpful, you can refer to this guidance to confirm it and help others with similar questions. 

    Thank you.  

    Was this answer helpful?

    1 person found this answer helpful.

  2. AI answer

    2026-11-04T04:57:44.5333333+00:00

    There is no documented public, non-mutating API that authoritatively classifies a named AppContainer profile as existing, absent, incomplete, or inaccessible; use CreateAppContainerProfile as the atomic lifecycle operation, and regard the returned S_OK as the evidence that this invocation created the profile.

    1. Profile existence and enumeration

    DeriveAppContainerSidFromAppContainerName is deterministic identity derivation. Its documented successful result means that Windows derived a SID from a valid name; its contract does not document profile existence or absence semantics.^1^

    The other public APIs do not provide a complete existence test either:

    • GetAppContainerFolderPath returns a profile folder path, not a profile-state record.
    • GetAppContainerRegistryLocation operates on the current profile and has no profile-name or package-SID argument, so it cannot query an arbitrary candidate profile.^2^
    • Undocumented HKCU mapping keys are not a supported contract and cannot reliably distinguish absence, partial state, access denial, or implementation changes.
    • A folder’s presence or absence is likewise not authoritative for the complete profile.

    NetworkIsolationEnumAppContainers enumerates created AppContainers and returns structures containing the AppContainer SID, user SID, and name.^3^ ^4^ It can therefore provide supplementary positive evidence, but its documentation does not define absence from the result as authoritative proof that a particular Userenv profile does not exist, nor does it promise classification of incomplete or inaccessible profiles.

    NETISO_FLAG_FORCE_COMPUTE_BINARIES only ensures current and complete binary information before each entry is returned. It does not document a registration refresh, synchronization barrier, or stronger absence guarantee.^3^

    2. Meaning of GetAppContainerFolderPath returning 0x80070002

    The documented GetAppContainerFolderPath contract specifies:

    • S_OK on success;
    • E_INVALIDARG for a null SID-string or output-pointer argument;
    • selection of the user context from the thread token, or otherwise from the process identity.^5^

    It does not document HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) as meaning “profile absent,” “registration missing,” or “profile incomplete.” 0x80070002 generally means that a file or resource required by that operation could not be found, but it is not by itself a component-specific diagnosis.^6^

    Consequently, your observed result establishes only this:

    • no path was returned in the effective token context;
    • the call failed because some required object or resource was not found;
    • the public contract does not expose which internal dependency was missing.

    It cannot safely be converted into an Absent state. Also ensure lifecycle calls run under the intended user token: thread impersonation changes which user GetAppContainerFolderPath uses.^5^

    3. Safe creation and ownership tracking

    Call CreateAppContainerProfile directly and branch on its documented result:

    1. S_OK — this invocation created the current user’s data store and returned its SID.
    2. HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS) — the data store pre-existed; do not adopt it for rollback or delete it.
    3. E_ACCESSDENIED — the caller lacks permission.
    4. Any other failure — do not record ownership and do not delete based merely on derived SID or filesystem observations.

    A profile contains per-user/per-app folders and registry storage. Creation applies to the current user unless the caller impersonates another user.^7^

    Keep an in-memory transaction record similar to:

    bool createdByThisOperation = false;
    IntPtr returnedSid = IntPtr.Zero;
    
    int hr = CreateAppContainerProfile(name, displayName, description,
                                       IntPtr.Zero, 0, out returnedSid);
    
    if (hr == 0) {
        createdByThisOperation = true;
        // Compare returned SID with the independently derived SID.
    } else if (hr == HRESULT_FROM_WIN32_ERROR_ALREADY_EXISTS) {
        // Existing profile: never mark owned and never roll it back.
    } else {
        Marshal.ThrowExceptionForHR(hr);
    }
    

    After S_OK, supported verification can include:

    • validate and retain the returned SID;
    • derive the SID from the same moniker and compare it with the returned SID;
    • call GetAppContainerFolderPath using the returned SID string;
    • retain the exact profile name, current-user identity, capability set, and every application-owned child resource.

    These checks detect inconsistencies, but they do not enumerate every registry and filesystem resource created internally. The supported success guarantee is that S_OK means the data store was created successfully.^7^

    4. Safe rollback and deletion

    Delete only when all of these are true:

    1. The same operation received S_OK from CreateAppContainerProfile.
    2. No ERROR_ALREADY_EXISTS path was taken.
    3. The exact creation name and intended user context were retained.
    4. All processes launched under that profile have exited.
    5. All application-owned file and registry handles associated with its storage are closed.

    Then call DeleteAppContainerProfile under the same user context. It deletes the current user’s named profile; deleting another user’s profile requires impersonating that user.^8^

    Important limitations:

    • Deleting a nonexistent profile also returns success, so S_OK does not prove that something previously existed.
    • Open storage handles can prevent complete storage removal.
    • If deletion fails, the profile state is documented as undetermined; call DeleteAppContainerProfile again to complete the operation.
    • No documented public API determines whether arbitrary processes are currently using the profile. Usage safety must come from controlling and joining your own child processes and closing your own handles.
    • Neither post-delete folder failure nor absence from network enumeration is documented as an authoritative complete-removal check.

    Therefore, the strongest defensible rollback statement is: a profile for which this operation received creation S_OK was passed to the supported deletion API after owned processes and handles were closed. The public contracts do not support asserting that every internal registration, registry key, and storage object was independently enumerated and verified absent.


    References

    1. DeriveAppContainerSidFromAppContainerName function (userenv.h)
    2. GetAppContainerRegistryLocation function (userenv.h)
    3. NetworkIsolationEnumAppContainers function (networkisolation.h)
    4. INET_FIREWALL_APP_CONTAINER structure (networkisolation.h)
    5. GetAppContainerFolderPath function (userenv.h)
    6. 0x80070002 Error code - Microsoft Q&A
    7. CreateAppContainerProfile function (userenv.h)
    8. DeleteAppContainerProfile function (userenv.h)
    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.