dotnet/wpf · error · ArgumentException

UriMustBeAbsolute

Error message

UriMustBeAbsolute

What it means

PackWebRequestFactory.Create (IWebRequestFactory.Create) requires an absolute pack:// URI. A relative Uri would throw a misleading InvalidOperationException later when reading Scheme, so Create proactively throws ArgumentException(SR.UriMustBeAbsolute). It also validates the scheme is 'pack' immediately afterwards.

Solutions

  1. Ensure the Uri is absolute, e.g. new Uri(baseUri, relative) or prepend "pack://application:,,,/".
  2. Validate uri.IsAbsoluteUri before calling Create.
  3. Use new Uri(uriString, UriKind.Absolute) so malformed input fails early at construction.

Example fix

// before
var req = WebRequest.Create(new Uri("/page.xaml", UriKind.Relative));
// after
var req = WebRequest.Create(new Uri("pack://application:,,,/page.xaml"));
Defensive patterns

Strategy: validation

Validate before calling

if (uri == null || !uri.IsAbsoluteUri) throw new ArgumentException("pack URI must be absolute", nameof(uri));

Type guard

static bool IsAbsolute(Uri u) => u is Uri x && x.IsAbsoluteUri;

Try / catch

try { return factory.Create(uri); }
catch (ArgumentException ex) when (ex.ParamName == nameof(uri)) { /* log / fix URI, e.g. resolve against pack://application:,,, base */ throw; }

Prevention

When it happens

Trigger: Calling WebRequest.Create / PackWebRequestFactory.Create with a relative Uri instance (uri.IsAbsoluteUri == false).

Common situations: Building URIs from config values or user input that omit the pack:// prefix; combining paths with Uri(...) without a base URI.

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/23cc1799e57fb28e. Report an issue: GitHub.

Appendix: source

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

        //
        //------------------------------------------------------
        /// <summary>
        /// Create
        /// </summary>
        /// <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);

View on GitHub (pinned to 81131a70a4)