dotnet/wpf · warning · UnauthorizedAccessException

E_ACCESSDENIED

E_ACCESSDENIED

Error message

UnauthorizedAccessException

What it means

The IAccessible server returned E_ACCESSDENIED and the provider maps it to UnauthorizedAccessException. The documented trigger in this code is calling get_accValue on a password control: MSAA deliberately refuses to hand back the masked value. This is an intentional security denial by the server, not a transient failure.

Solutions

  1. Do not read password field values via UIA/MSAA — restructure the test to verify the field has focus/type instead of its content.
  2. Check AccessibilityObject properties on your own controls; clear ES_PASSWORD only in controlled test builds if you truly need the value.
  3. Catch UnauthorizedAccessException around Value retrieval and treat it as 'field is protected'.
  4. Use the app's own instrumentation (test hooks, logs) to obtain the value rather than scraping protected UI.

Example fix

// before
var pwd = pwdBox.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
var value = pwd.Current.Value; // UnauthorizedAccessException for password fields
// after
var isPassword = (bool)pwdBox.GetCurrentPropertyValue(AutomationElement.IsPasswordProperty, true);
if (isPassword)
{
    // verify behavior (focus, type, keystrokes) instead of reading the value
}
else
{
    var value = ((ValuePattern)pwdBox.GetCurrentPattern(ValuePattern.Pattern)).Current.Value;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Skip protected fields before reading values:
bool IsPasswordField(AutomationElement el) =>
    (bool)el.GetCurrentPropertyValue(AutomationElement.IsPasswordProperty, true);

Try / catch

try
{
    var v = ((ValuePattern)el.GetCurrentPattern(ValuePattern.Pattern)).Current.Value;
}
catch (UnauthorizedAccessException)
{
    // password/protected field: do not attempt further reads
}

Prevention

When it happens

Trigger: Reading the ValuePattern/value property of an Edit control with ES_PASSWORD style through the MSAA client-side provider; any other IAccessible property call the server refuses with E_ACCESSDENIED.

Common situations: Automation or test tooling trying to read a login/password textbox's value; screen-scraping tools hitting masked fields; UI tests asserting on credential fields.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/4c6a8a7256903c87. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/UIAutomation/UIAutomationClientSideProviders/MS/Internal/AutomationProxies/Accessible.cs:1360

                        // just return on E_NOTIMPL errors
                        return false;

                    case NativeMethods.E_OUTOFMEMORY:
                        // Some OLEACC proxies produce out-of-memory for non-critical reasons:
                        // notably, the treeview proxy will raise this if the target HWND no longer exists,
                        // GetWindowThreadProcessID fails and it therefore won't be able to allocate shared
                        // memory in the target process, so it incorrectly assumes OOM.
                        throw new ElementNotAvailableException(e);
                        
                    case NativeMethods.E_INVALIDARG:
                        // One or more arguments were invalid. This error occurs when the caller attempts to identify
                        // a child object using an identifier that the server does not recognize. This error also results
                        // when a client attempts to identify a child object within an object that has no children.
                        throw new ArgumentException(SR.InvalidParameter);

                    case NativeMethods.E_ACCESSDENIED:
                        // This is returned when you call get_accValue to get the value of a password control.
                        throw new UnauthorizedAccessException();

                    case NativeMethods.E_UNEXPECTED:
                        // An IAccessible server has been released unexpectedly but still has pending events.
                        // If the current execution context is inside one of these event handlers it must be 
                        // abandoned.
                        throw new ElementNotAvailableException(e);

                    default:
                        // we want to know when we get an exception we haven't seen before
                        Debug.Fail(string.Format(CultureInfo.CurrentCulture, "MsaaNativeProvider: IAccessible threw a COMException: {0}", e.Message));
                        break;
                }
            }
            else if (e is InvalidCastException)
            {
                // sometimes Trident throws InvalidCastExceptions on elements from obsolete pages
                throw new ElementNotAvailableException(e);
            }

View on GitHub (pinned to 81131a70a4)