dotnet/maui · critical · InvalidOperationException
NavigationPage must have a root Page before being used. Eith
Error message
NavigationPage must have a root Page before being used. Either call PushAsync with a valid Page, or pass a Page to the constructor before usage.
What it means
In NavigationRenderer.ViewDidLoad, after setting up the toolbar, the renderer checks NavPage.CurrentPage. If null, the NavigationPage has no root page - the iOS navigation controller cannot function without at least one page on its stack, and later code (line 246) iterates NavPageController.Pages and pushes them. So it throws InvalidOperationException with a clear remediation message.
Source
Thrown at src/Compatibility/Core/src/iOS/Renderers/NavigationRenderer.cs:227
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
UpdateTranslucent();
_secondaryToolbar = new SecondaryToolbar { Frame = new RectangleF(0, 0, 320, 44) };
View.Add(_secondaryToolbar);
_secondaryToolbar.Hidden = true;
FindParentFlyoutPage();
var navPage = NavPage;
INavigationPageController navPageController = NavPage;
if (navPage.CurrentPage == null)
{
throw new InvalidOperationException(
"NavigationPage must have a root Page before being used. Either call PushAsync with a valid Page, or pass a Page to the constructor before usage.");
}
navPageController.PushRequested += OnPushRequested;
navPageController.PopRequested += OnPopRequested;
navPageController.PopToRootRequested += OnPopToRootRequested;
navPageController.RemovePageRequested += OnRemovedPageRequested;
navPageController.InsertPageBeforeRequested += OnInsertPageBeforeRequested;
UpdateBarBackground();
UpdateBarTextColor();
UpdateHideNavigationBarSeparator();
UpdateUseLargeTitles();
if (OperatingSystem.IsIOSVersionAtLeast(11))
SetNeedsUpdateOfHomeIndicatorAutoHidden();
// If there is already stuff on the stack we need to push itView on GitHub (pinned to f377ff1c5e)
Solutions
- Pass a root page to the NavigationPage constructor: new NavigationPage(new RootPage()).
- If constructing empty, call PushAsync(rootPage) before the page is shown.
- Ensure the NavigationPage is not rendered until at least one child page exists.
Example fix
// before MainPage = new NavigationPage(); // no root page // after MainPage = new NavigationPage(new RootPage());
Defensive patterns
Strategy: validation
Validate before calling
// Before setting MainPage:
var nav = new NavigationPage();
if (nav.CurrentPage == null)
nav.PushAsync(new RootPage());
MainPage = nav;
// Simplest: pass root in ctor
MainPage = new NavigationPage(new RootPage()); Prevention
- Always seed NavigationPage with a root page in its constructor.
- Never remove the last page from a NavigationPage stack.
When it happens
Trigger: Constructing a NavigationPage with the parameterless constructor and never pushing/adding a page before it is rendered on iOS; or pushing a null page; or removing the last page so the stack becomes empty before ViewDidLoad runs.
Common situations: new NavigationPage() with no page passed and no PushAsync before display; binding MainPage to a NavigationPage whose Children is empty initially; removing all pages from the stack while the renderer is loading.
Related errors
- InsertPageBefore is not supported globally on iOS, please us
- PopAsync is not supported globally on iOS, please use a Navi
- PopToRootAsync is not supported globally on iOS, please use
- PushAsync is not supported globally on iOS, please use a Nav
- RemovePage is not supported globally on iOS, please use a Na
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/f1f066c6a2619fa3.
Report an issue: GitHub.