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
- Ensure the Uri is absolute, e.g. new Uri(baseUri, relative) or prepend "pack://application:,,,/".
- Validate uri.IsAbsoluteUri before calling Create.
- 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
- Build pack URIs with new Uri("pack://application:,,,/" + path, UriKind.Absolute)
- Resolve relative paths against a base pack URI with new Uri(baseUri, relative)
- Use UriKind.Absolute so bad input fails at construction
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
- SR.AbsoluteUriOnly
- SR.Effect_SourceUriMustBeFileOrPack
- SR.Format(SR.ArgumentPropertyMustNotBeNull, "uriRemote"…
- SR.Format(SR.InvalidCtorParameterNoNaN, "value")
- SR.InvalidPropertyValue
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)