dotnet/wpf · error · MS.Internal.Security.RightsManagement.RightsManagementException

SR.RmExceptionGenericMessage

Error message

SR.RmExceptionGenericMessage

What it means

Fallback path in Errors.ThrowOnErrorCode: when the HRESULT has no localized RM failure-code message, the library lets Marshal.ThrowExceptionForHR throw, and if that produces an exception it wraps it in RightsManagementException with the generic SR.RmExceptionGenericMessage and the original exception as InnerException.

Solutions

  1. Inspect the InnerException of the RightsManagementException — it holds the real HR/cause.
  2. Repair/reinstall the AD RMS client (MSIPC) and confirm DRM DLLs are intact.
  3. Retry the operation; transient native failures (resources, handles) often clear on a fresh session.
  4. Log the original HRESULT from the inner exception and search it against DRM failure-code docs.

Example fix

// before: only message is 'generic RM exception'
catch (RightsManagementException ex) { Log(ex.Message); }

// after
catch (RightsManagementException ex)
{
    Log($"{ex.Message} caused by {ex.InnerException?.HResult:x8}: {ex.InnerException?.Message}");
}
Defensive patterns

Strategy: try-catch

Try / catch

catch (RightsManagementException ex) when (ex.InnerException != null)
{
    int hr = ex.InnerException.HResult;
    Log($"Unmapped DRM HRESULT 0x{hr:X8}: {ex.InnerException.Message}");
}

Prevention

When it happens

Trigger: Native DRM API returned an HRESULT unknown to the failure-code table (e.g. low-level COM/Win32 errors from the secure environment, corrupted DRM stack state, E_HANDLE/E_OUTOFMEMORY from the client session).

Common situations: Broken or outdated RMS client installation; memory/handle exhaustion during long sessions; OS-level security components failing; unexpected native states not covered by the localized message table.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/Security/RightsManagement/Errors.cs:61

            string errorMessage = GetLocalizedFailureCodeMessage((RightsManagementFailureCode)hr);
            if (errorMessage != null)
            {
                throw new RightsManagementException((RightsManagementFailureCode)hr, errorMessage);
            }
            else
            {
                try
                {
                    // It seems that ThrowExceptionForHR is the most consistent way
                    // to get a platform representation of the unmanaged HR code
                    Marshal.ThrowExceptionForHR(hr);
                }
                // We are re-throwing the same exception wrapped in a more specific message
                catch (Exception e)
                {
                    // rethrow the exception as an inner exception of the RmExceptionGenericMessage
                    throw new RightsManagementException(SR.RmExceptionGenericMessage, e);
                }
            }
        }

        private static string GetLocalizedFailureCodeMessage(RightsManagementFailureCode failureCode)
        {
            string result;
            switch (failureCode)
            {
                case RightsManagementFailureCode.InvalidLicense:
                    result=nameof(SR.RmExceptionInvalidLicense); break;
                case RightsManagementFailureCode.InfoNotInLicense:
                    result=nameof(SR.RmExceptionInfoNotInLicense); break;
                case RightsManagementFailureCode.InvalidLicenseSignature:
                    result=nameof(SR.RmExceptionInvalidLicenseSignature); break;
                case RightsManagementFailureCode.EncryptionNotPermitted:
                    result=nameof(SR.RmExceptionEncryptionNotPermitted); break;
                case RightsManagementFailureCode.RightNotGranted:

View on GitHub (pinned to 81131a70a4)