dotnet/aspnetcore · error · ArgumentException
The URI ' ' is not contained by the base URI ' '.
Error message
The URI '{uri}' is not contained by the base URI '{baseUri}'. What it means
Thrown by the private Validate helper invoked from the Uri setter whenever the new absolute URI is not prefixed by the configured base URI. This guards the invariant that NavigationManager.Uri always lives inside BaseUri; setting anything else would corrupt relative-URI resolution for every subsequent call.
Solutions
- Before assigning Uri, confirm it starts with BaseUri.OriginalString; if not, re-Initialize with matching base/uri.
- Keep <base href> stable across deployments, or migrate old URLs via redirect to the new base before they reach NavigationManager.
- In tests, set BaseUri first, then Uri; use NavigationManager.Initialize(baseUri, uri) to set both atomically.
- When restoring history state, validate the stored URI against the current BaseUri and discard entries that no longer match.
Example fix
// before: assigning a Uri that crossed the base after a subpath change
BaseUri = "https://site.com/app/";
Uri = "https://site.com/old-path/page"; // throws
// after: re-initialize with a URI inside the base
Initialize("https://site.com/app/", "https://site.com/app/page"); Defensive patterns
Strategy: validation
Validate before calling
static bool WithinBase(Uri baseUri, string uri) => uri.StartsWith(baseUri.OriginalString, StringComparison.Ordinal);
if (!WithinBase(baseUri, newUri)) throw new InvalidOperationException("Refusing to set Uri outside BaseUri."); Try / catch
try { manager.Uri = candidate; }
catch (ArgumentException ex) when (ex.Message.Contains("not contained by the base URI"))
{ /* reject the candidate, log, fall back */ } Prevention
- Set BaseUri before Uri; use Initialize(baseUri, uri) to set both atomically.
- Validate restored history URIs against the current BaseUri and discard mismatches.
- Keep <base href> stable across deployments; redirect old URLs to the new base before they reach NavigationManager.
When it happens
Trigger: A subclass (or framework host code) assigns an absolute URI to the protected Uri setter that lives outside BaseUri - e.g. restoring a deep link after the <base href> changed, a history entry from a previous deployment, or a programmatic NavigateTo whose resolved absolute form crosses the base boundary.
Common situations: Redeploying the app under a new subpath while old history entries still point at the previous base; a server-side redirect landing outside the configured base; manipulating NavigationManager.Uri in tests without aligning BaseUri first.
Related errors
- The URI ' ' is not contained by the base URI ' '.
- An exception occurred while dispatching a location changed…
- Cannot format query parameters with values of type
- Cannot have empty query parameter names.
- ' ' has not been initialized.
AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11).
Data as JSON: /api/errors/8d68b1c26a52577e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Components/Components/src/NavigationManager.cs:653
length = baseUri.OriginalString.Length - 1;
return true;
}
length = 0;
return false;
}
private static void Validate(Uri? baseUri, string uri)
{
if (baseUri == null || uri == null)
{
return;
}
if (!TryGetLengthOfBaseUriPrefix(baseUri, uri, out _))
{
var message = $"The URI '{uri}' is not contained by the base URI '{baseUri}'.";
throw new ArgumentException(message);
}
}
private sealed class LocationChangingRegistration : IDisposable
{
private readonly Func<LocationChangingContext, ValueTask> _handler;
private readonly NavigationManager _navigationManager;
public LocationChangingRegistration(Func<LocationChangingContext, ValueTask> handler, NavigationManager navigationManager)
{
_handler = handler;
_navigationManager = navigationManager;
}
public void Dispose()
{
_navigationManager.RemoveLocationChangingHandler(_handler);
}View on GitHub (pinned to 3600ca084e)