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 NavigationManager.ToBaseRelativePath(string) when the supplied absolute URI does not start with the configured base URI string (and the trailing-slash special case does not match). The library requires every absolute URI it converts to live inside the application's base URI space so the relative path is well-defined. The check is an ordinal string-prefix comparison, with one carve-out for a base like "/app/" accepting the no-slash form "/app".

Solutions

  1. Ensure the <base href> in wwwroot/index.html (WebAssembly) or App.razor/_Host.cshtml (Server) exactly matches the deployed application path including the trailing slash.
  2. Pass URIs sourced from NavigationManager.Uri rather than window.location.href or hardcoded strings, so they are guaranteed to share the base prefix.
  3. If hosting under a subpath, configure the app to use that subpath as PathBase (app.UsePathBase("/myapp")) and set <base href="/myapp/"> accordingly.
  4. Verify the reverse proxy forwards the original host/path headers (X-Forwarded-Host, X-Forwarded-Proto) and that ASP.NET Core's ForwardedHeaders middleware is enabled.

Example fix

// before: hardcoded URL breaks when deployed under a subpath
var relative = navManager.ToBaseRelativePath("https://contoso.com/page");

// after: derive from the manager's own URI, which always shares BaseUri
var relative = navManager.ToBaseRelativePath(navManager.Uri);
Defensive patterns

Strategy: validation

Validate before calling

private static bool IsWithinBase(string baseUri, string uri)
{
    if (uri.StartsWith(baseUri, StringComparison.Ordinal)) return true;
    var pathEnd = uri.AsSpan().IndexOfAny('#', '?');
    var pathOnly = pathEnd < 0 ? uri : uri.AsSpan(0, pathEnd);
    return baseUri.EndsWith('/') && pathOnly.SequenceEqual(baseUri.AsSpan(0, baseUri.Length - 1));
}

// usage
var uri = navManager.Uri;
if (!IsWithinBase(navManager.BaseUri, uri)) throw new InvalidOperationException("URI is outside the configured base.");

Try / catch

try { var rel = navManager.ToBaseRelativePath(candidate); }
catch (ArgumentException ex) when (ex.Message.Contains("not contained by the base URI"))
{ /* log and fall back to NavManager.Uri or reject the navigation */ }

Prevention

When it happens

Trigger: Calling navigationManager.ToBaseRelativePath(absoluteUri) where absoluteUri was produced by a different host, scheme, port, or path prefix than BaseUri. Common when the <base href> differs from the request URL (reverse proxy, subpath hosting, prerender vs. client mismatch), or when a hardcoded absolute URL is passed instead of a value derived from NavigationManager.Uri.

Common situations: App deployed under a subpath (e.g. /myapp/) but <base href="/"> in index.html/_Host.cshtml; reverse proxy stripping or rewriting the path; WebAssembly client reading window.location.href directly while the host serves from a different base; cross-origin redirect URLs passed to ToBaseRelativePath.

Related errors


AI-assisted analysis of dotnet/aspnetcore@3600ca084e (2026-08-11). Data as JSON: /api/errors/af2ab4677fbf7118. Report an issue: GitHub.

Appendix: source

Thrown at src/Components/Components/src/NavigationManager.cs:347

            // baseUri ends with a slash), and from that we return "something"
            return uri.Substring(_baseUri.OriginalString.Length);
        }

        var pathEndIndex = uri.AsSpan().IndexOfAny('#', '?');
        var uriPathOnly = pathEndIndex < 0 ? uri : uri.AsSpan(0, pathEndIndex);
        if (_baseUri.OriginalString.EndsWith('/') && uriPathOnly.Equals(_baseUri.OriginalString.AsSpan(0, _baseUri.OriginalString.Length - 1), StringComparison.Ordinal))
        {
            // Special case: for the base URI "/something/", if you're at
            // "/something" then treat it as if you were at "/something/" (i.e.,
            // with the trailing slash). It's a bit ambiguous because we don't know
            // whether the server would return the same page whether or not the
            // slash is present, but ASP.NET Core at least does by default when
            // using PathBase.
            return uri.Substring(_baseUri.OriginalString.Length - 1);
        }

        var message = $"The URI '{uri}' is not contained by the base URI '{_baseUri}'.";
        throw new ArgumentException(message);
    }

    internal ReadOnlySpan<char> ToBaseRelativePath(ReadOnlySpan<char> uri)
    {
        if (MemoryExtensions.StartsWith(uri, _baseUri!.OriginalString.AsSpan(), StringComparison.Ordinal))
        {
            // The absolute URI must be of the form "{baseUri}something" (where
            // baseUri ends with a slash), and from that we return "something"
            return uri[_baseUri.OriginalString.Length..];
        }

        var pathEndIndex = uri.IndexOfAny('#', '?');
        var uriPathOnly = pathEndIndex < 0 ? uri : uri[..pathEndIndex];
        if (_baseUri.OriginalString.EndsWith('/') && MemoryExtensions.Equals(uriPathOnly, _baseUri.OriginalString.AsSpan(0, _baseUri.OriginalString.Length - 1), StringComparison.Ordinal))
        {
            // Special case: for the base URI "/something/", if you're at
            // "/something" then treat it as if you were at "/something/" (i.e.,
            // with the trailing slash). It's a bit ambiguous because we don't know

View on GitHub (pinned to 3600ca084e)