dotnet/aspnetcore · error · ArgumentException

The URI '{uri}' is not contained by the base URI '{_baseUri}

Error message

The URI '{uri}' is not contained by the base URI '{_baseUri}'.

What it means

The public ToBaseRelativePath(string) throws ArgumentException when the given absolute URI is neither prefixed by the base URI nor matches the base-without-trailing-slash special case. Blazor uses this to convert absolute URLs to relative paths for routing, so a mismatch means the URI is outside the app's base path.

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 294cab2f9b)

Solutions

  1. Ensure the URI passed to ToBaseRelativePath is under the configured BaseUri (same scheme/host/path-prefix).
  2. Fix the <base href> tag or BaseUri initialization to match the actual deployment path.
  3. Handle cross-origin URIs separately instead of routing them through ToBaseRelativePath.

Example fix

// before (BaseUri = http://app/subdir/)
var rel = navManager.ToBaseRelativePath("http://other-host/page");

// after
var rel = navManager.ToBaseRelativePath("http://app/subdir/page");
Defensive patterns

Strategy: validation

Validate before calling

static string SafeToBaseRelative(NavigationManager nm, string uri)
{
    var baseUri = nm.BaseUri;
    if (!uri.StartsWith(baseUri, StringComparison.Ordinal))
        throw new ArgumentException($"{uri} is outside base {baseUri}");
    return nm.ToBaseRelativePath(uri);
}

Type guard

static bool IsUnderBaseUri(string baseUri, string uri) =>
    uri.StartsWith(baseUri, StringComparison.Ordinal) ||
    (baseUri.EndsWith('/') && uri == baseUri[..^1]);

Try / catch

try { return navManager.ToBaseRelativePath(uri); }
catch (ArgumentException ex) when (ex.Message.Contains("not contained by the base URI"))
{ logger.LogWarning(ex, "URI outside base path"); return uri; }

Prevention

When it happens

Trigger: Calling ToBaseRelativePath with an absolute URI on a different host/scheme than BaseUri; BaseUri changed (e.g. behind a reverse proxy) but the URI is from the old base; path-only URI passed where an absolute URI was expected.

Common situations: App moved behind a different path prefix; misconfigured <base href> causing BaseUri mismatch; cross-origin links being processed by the router; reverse proxy stripping/adding path prefixes.

Related errors


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