dotnet/wpf · error · FileFormatException

SR.Format(SR.InvalidAuthenticationTypeString…

Error message

SR.Format(SR.InvalidAuthenticationTypeString, typePrefixedUserName)

What it means

After splitting the type prefix, ParseTypePrefixedUserName matches it case-insensitively against AuthenticationType constants Windows and Passport. An unrecognized prefix throws FileFormatException with SR.InvalidAuthenticationTypeString formatted with the full type-prefixed user name.

Solutions

  1. Change the prefix to 'windows' or 'passport' to match AuthenticationType constants
  2. Rebuild the ContentUser with AuthenticationType.Windows or AuthenticationType.Passport so the correct prefix is stored
  3. Regenerate/re-save the document from the original RM writer
  4. Catch FileFormatException to report the unsupported authentication scheme gracefully

Example fix

// before
var user = new ContentUser("liveid:foo@bar.com", AuthenticationType.Windows);
// after
var user = new ContentUser("passport:foo@hotmail.com", AuthenticationType.Passport);
Defensive patterns

Strategy: try-catch

Validate before calling

static bool IsSupportedAuthPrefix(string s) { int i = s.IndexOf(':'); var p = i > 0 ? s.Substring(0, i) : ""; return p.Equals("Windows", StringComparison.OrdinalIgnoreCase) || p.Equals("Passport", StringComparison.OrdinalIgnoreCase); }

Type guard

bool HasSupportedAuthenticationType(string typePrefixedUserName) { var prefix = typePrefixedUserName.Split(':')[0]; return prefix.Equals(nameof(AuthenticationType.Windows), StringComparison.OrdinalIgnoreCase) || prefix.Equals(nameof(AuthenticationType.Passport), StringComparison.OrdinalIgnoreCase); }

Try / catch

try { ParseTypePrefixedUserName(raw, out _, out _); } catch (FileFormatException ex) { /* unsupported auth prefix: report unsupported scheme */ }

Prevention

When it happens

Trigger: Reading a use-license stream whose user name prefix is neither 'windows' nor 'passport' (case-insensitive), e.g. 'liveid:...' or a misspelled prefix like 'windws:'.

Common situations: Documents produced by third-party RM writers using other auth schemes; typos when constructing ContentUser names manually; format evolution between RM implementations.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/MS/Internal/IO/Packaging/CompoundFile/RightsManagementEncryptionTransform.cs:1072

            // parameter.
            int colonIndex = typePrefixedUserName.IndexOf(':');
            if (colonIndex < 1 || colonIndex >= typePrefixedUserName.Length - 1)
            {
                throw new FileFormatException(SR.InvalidTypePrefixedUserName);
            }

            // No need to use checked{} here since colonIndex cannot be >= to (max int - 1)
            userName = typePrefixedUserName.Substring(colonIndex + 1);

            // Usernames: Case-Insensitive comparison
            ReadOnlySpan<char> authenticationSpan = typePrefixedUserName.AsSpan(0, colonIndex);

            if (authenticationSpan.Equals(nameof(AuthenticationType.Windows), StringComparison.OrdinalIgnoreCase))
                authenticationType = AuthenticationType.Windows;
            else if (authenticationSpan.Equals(nameof(AuthenticationType.Passport), StringComparison.OrdinalIgnoreCase))
                authenticationType = AuthenticationType.Passport;
            else // Didn't find a matching enumeration constant.
                throw new FileFormatException(SR.Format(SR.InvalidAuthenticationTypeString, typePrefixedUserName));
        }

        /// <summary>
        /// Load the use license from the specified stream.
        /// </summary>
        /// <param name="utf8Reader">
        /// The Utf 8 BinaryReader from which the use license is to be loaded.
        /// </param>
        /// <returns>
        /// The use license from the stream.
        /// </returns>
        /// <remarks>
        /// For details of the stream format, see the comments in LoadUseLicenseAndUserFromStream.
        /// </remarks>
        private UseLicense
        LoadUseLicenseFromStream(
            BinaryReader utf8Reader
            )

View on GitHub (pinned to 81131a70a4)