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
- Do not read password field values via UIA/MSAA — restructure the test to verify the field has focus/type instead of its content.
- Check AccessibilityObject properties on your own controls; clear ES_PASSWORD only in controlled test builds if you truly need the value.
- Catch UnauthorizedAccessException around Value retrieval and treat it as 'field is protected'.
- 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
- Check AutomationElement.IsPasswordProperty before reading Value.
- Never assert on credential field contents in automated tests; assert on behavior instead.
- Avoid scraping masked UI fields — use app-level test hooks for sensitive data.
- Treat UnauthorizedAccessException from MSAA reads as a permanent, not retryable, denial.
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.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
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)