{"record":{"id":"af2ab4677fbf7118","repo":"dotnet/aspnetcore","slug":"the-uri-uri-is-not-contained-by-the-base-uri","errorCode":null,"errorMessage":"The URI '{uri}' is not contained by the base URI '{_baseUri}'.","messagePattern":"The URI '(.+?)' is not contained by the base URI '(.+?)'\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Components/Components/src/NavigationManager.cs","lineNumber":347,"sourceCode":"            // baseUri ends with a slash), and from that we return \"something\"\n            return uri.Substring(_baseUri.OriginalString.Length);\n        }\n\n        var pathEndIndex = uri.AsSpan().IndexOfAny('#', '?');\n        var uriPathOnly = pathEndIndex < 0 ? uri : uri.AsSpan(0, pathEndIndex);\n        if (_baseUri.OriginalString.EndsWith('/') && uriPathOnly.Equals(_baseUri.OriginalString.AsSpan(0, _baseUri.OriginalString.Length - 1), StringComparison.Ordinal))\n        {\n            // Special case: for the base URI \"/something/\", if you're at\n            // \"/something\" then treat it as if you were at \"/something/\" (i.e.,\n            // with the trailing slash). It's a bit ambiguous because we don't know\n            // whether the server would return the same page whether or not the\n            // slash is present, but ASP.NET Core at least does by default when\n            // using PathBase.\n            return uri.Substring(_baseUri.OriginalString.Length - 1);\n        }\n\n        var message = $\"The URI '{uri}' is not contained by the base URI '{_baseUri}'.\";\n        throw new ArgumentException(message);\n    }\n\n    internal ReadOnlySpan<char> ToBaseRelativePath(ReadOnlySpan<char> uri)\n    {\n        if (MemoryExtensions.StartsWith(uri, _baseUri!.OriginalString.AsSpan(), StringComparison.Ordinal))\n        {\n            // The absolute URI must be of the form \"{baseUri}something\" (where\n            // baseUri ends with a slash), and from that we return \"something\"\n            return uri[_baseUri.OriginalString.Length..];\n        }\n\n        var pathEndIndex = uri.IndexOfAny('#', '?');\n        var uriPathOnly = pathEndIndex < 0 ? uri : uri[..pathEndIndex];\n        if (_baseUri.OriginalString.EndsWith('/') && MemoryExtensions.Equals(uriPathOnly, _baseUri.OriginalString.AsSpan(0, _baseUri.OriginalString.Length - 1), StringComparison.Ordinal))\n        {\n            // Special case: for the base URI \"/something/\", if you're at\n            // \"/something\" then treat it as if you were at \"/something/\" (i.e.,\n            // with the trailing slash). It's a bit ambiguous because we don't know","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Components/src/NavigationManager.cs#L329-L365","documentation":"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\".","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","Pass URIs sourced from NavigationManager.Uri rather than window.location.href or hardcoded strings, so they are guaranteed to share the base prefix.","If hosting under a subpath, configure the app to use that subpath as PathBase (app.UsePathBase(\"/myapp\")) and set <base href=\"/myapp/\"> accordingly.","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."],"exampleFix":"// before: hardcoded URL breaks when deployed under a subpath\nvar relative = navManager.ToBaseRelativePath(\"https://contoso.com/page\");\n\n// after: derive from the manager's own URI, which always shares BaseUri\nvar relative = navManager.ToBaseRelativePath(navManager.Uri);","handlingStrategy":"validation","validationCode":"private static bool IsWithinBase(string baseUri, string uri)\n{\n    if (uri.StartsWith(baseUri, StringComparison.Ordinal)) return true;\n    var pathEnd = uri.AsSpan().IndexOfAny('#', '?');\n    var pathOnly = pathEnd < 0 ? uri : uri.AsSpan(0, pathEnd);\n    return baseUri.EndsWith('/') && pathOnly.SequenceEqual(baseUri.AsSpan(0, baseUri.Length - 1));\n}\n\n// usage\nvar uri = navManager.Uri;\nif (!IsWithinBase(navManager.BaseUri, uri)) throw new InvalidOperationException(\"URI is outside the configured base.\");","typeGuard":null,"tryCatchPattern":"try { var rel = navManager.ToBaseRelativePath(candidate); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"not contained by the base URI\"))\n{ /* log and fall back to NavManager.Uri or reject the navigation */ }","preventionTips":["Always source URIs from NavigationManager.Uri rather than window.location.href or hardcoded strings.","Keep <base href> aligned with the deployed subpath and PathBase configuration.","In tests, call Initialize(baseUri, uri) with matching values before exercising ToBaseRelativePath.","When hosting behind a reverse proxy, enable ForwardedHeaders middleware so BaseUri reflects the original URL."],"tags":["blazor","routing","uri","configuration"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}