dotnet/wpf · error · ArgumentException

UriSchemeMismatch (pack)

Error message

UriSchemeMismatch (pack)

What it means

PackWebRequestFactory.Create can be invoked directly (not only through WebRequest.Create scheme dispatch), so it re-checks the URI scheme itself. If uri.Scheme is not exactly "pack" (case-sensitive ordinal comparison; Uri.Scheme is always lowercase), it throws ArgumentException with SR.UriSchemeMismatch naming the expected scheme.

Solutions

  1. Pass a pack:// scheme URI, e.g. pack://application:,,,/path or pack://siteoforigin:,,,/file.
  2. Check uri.Scheme == PackUriHelper.UriSchemePack before calling the factory.
  3. Use WebRequest.Create(uri) and let scheme dispatch pick the right factory.

Example fix

// before
var req = factory.Create(new Uri("http://example.com/file.xaml"));
// after
var req = factory.Create(new Uri("pack://http:,,example.com,file.xaml"));
Defensive patterns

Strategy: validation

Validate before calling

if (!string.Equals(uri?.Scheme, "pack", StringComparison.Ordinal)) throw new ArgumentException("expected pack:// scheme", nameof(uri));

Type guard

static bool IsPackUri(Uri u) => u?.IsAbsoluteUri == true && u.Scheme == "pack";

Try / catch

try { return factory.Create(uri); }
catch (ArgumentException ex) when (ex.Message.Contains("pack")) { uri = new Uri("pack://application:,,," + uri.PathAndQuery); return factory.Create(uri); }

Prevention

When it happens

Trigger: Calling PackWebRequestFactory.Create with an absolute Uri whose scheme is not pack (e.g. http://, file://, application:///).

Common situations: Passing a generic HTTP URI into a factory that is registered for pack URIs; misconfigured URI templates that drop the pack:// prefix; calling the factory directly instead of via WebRequest.Create.

Understand the failure class

Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/IO/Packaging/PackWebRequestFactory.cs:60

        /// <param name="uri">uri</param>
        /// <returns>PackWebRequest</returns>
        /// <remarks>Note that this factory may or may not be "registered" with the .NET WebRequest factory as handler
        /// for "pack" scheme web requests.  Because of this, callers should be sure to use the PackUriHelper static class
        /// to prepare their Uri's.  Calling any PackUriHelper method has the side effect of registering
        /// the "pack" scheme and associating this factory class as its default handler.</remarks>
        WebRequest IWebRequestCreate.Create(Uri uri)
        {
            ArgumentNullException.ThrowIfNull(uri);

            // Ensure uri is absolute - if we don't check now, the get_Scheme property will throw 
            // InvalidOperationException which would be misleading to the caller.
            if (!uri.IsAbsoluteUri)
                throw new ArgumentException(SR.UriMustBeAbsolute, nameof(uri));

            // Ensure uri is correct scheme because we can be called directly.  Case sensitive
            // is fine because Uri.Scheme contract is to return in lower case only.
            if (!string.Equals(uri.Scheme, PackUriHelper.UriSchemePack, StringComparison.Ordinal))
                throw new ArgumentException(SR.Format(SR.UriSchemeMismatch, PackUriHelper.UriSchemePack), nameof(uri));

#if DEBUG
            if (_traceSwitch.Enabled)
                System.Diagnostics.Trace.TraceInformation(
                        DateTime.Now.ToLongTimeString() + " " + DateTime.Now.Millisecond + " " +
                        Environment.CurrentManagedThreadId + ": " + 
                        "PackWebRequestFactory - responding to uri: " + uri);
#endif
            // only inspect cache if part name is present because cache only contains an object, not
            // the stream it was derived from
            Uri packageUri = System.IO.Packaging.PackUriHelper.GetPackageUri(uri);
            Uri partUri = System.IO.Packaging.PackUriHelper.GetPartUri(uri);

            if (partUri != null)
            {
                // Note: we look at PreloadedPackages first before we examine the PackageStore
                //  This is to make sure that an app cannot override any predefine packages

View on GitHub (pinned to 81131a70a4)