dotnet/maui · critical · NotSupportedException
Popped page does not appear on top of current navigation sta
Error message
Popped page does not appear on top of current navigation stack, please file a bug.
What it means
OnPopViewAsync verifies that the page being popped matches the Child of the current TopViewController (a ParentingViewController). If they differ, the platform's notion of the top of the stack disagrees with the MAUI logical stack - a state corruption. It throws NotSupportedException asking the user to file a bug because this is an unexpected internal-state mismatch.
Source
Thrown at src/Compatibility/Core/src/iOS/Renderers/NavigationRenderer.cs:336
_ignorePopCall = false;
var success = !await task;
UpdateToolBarVisible();
return success;
}
protected virtual async Task<bool> OnPopViewAsync(Page page, bool animated)
{
if (_ignorePopCall)
return true;
var renderer = Platform.GetRenderer(page);
if (renderer == null || renderer.ViewController == null)
return false;
if (page != ((ParentingViewController)TopViewController).Child)
throw new NotSupportedException("Popped page does not appear on top of current navigation stack, please file a bug.");
var task = GetAppearedOrDisappearedTask(page);
UIViewController poppedViewController;
_ignorePopCall = true;
poppedViewController = base.PopViewController(animated);
var actuallyRemoved = poppedViewController == null ? true : !await task;
_ignorePopCall = false;
poppedViewController?.Dispose();
UpdateToolBarVisible();
return actuallyRemoved;
}
protected virtual async Task<bool> OnPushAsync(Page page, bool animated)
{View on GitHub (pinned to f377ff1c5e)
Solutions
- Avoid mixing NavigationPage.PushAsync/PopAsync with direct UINavigationController calls.
- Serialise navigation operations (await each Push/Pop) to prevent overlapping mutations.
- Ensure RemovePage/InsertPageBefore are not called while a Pop is in flight.
- If reproducible, report with the exact navigation sequence and MAUI version.
Example fix
// before (concurrent navigation) _ = Navigation.PopAsync(); Navigation.InsertPageBefore(other, current); // after (serialised) await Navigation.PopAsync(); Navigation.InsertPageBefore(other, current);
Defensive patterns
Strategy: try-catch
Try / catch
try { await Navigation.PopAsync(animated); }
catch (NotSupportedException ex) when (ex.Message.Contains("navigation stack"))
{
// stack desync - resync by reading Navigation.NavigationStack
// and avoid concurrent navigation
} Prevention
- Await each PushAsync/PopAsync before issuing the next.
- Never mix NavigationPage APIs with direct UINavigationController calls.
- Avoid calling RemovePage during an in-flight Pop.
When it happens
Trigger: A PopAsync/PopAsync(page) call where the requested page is not actually the top of the iOS view-controller stack; concurrent/mismatched Push/Pop/InsertPageBefore/RemovePage calls; manually calling base.PopViewController elsewhere; custom navigation that mutates ViewControllers directly.
Common situations: Mixing NavigationPage methods with custom UINavigationController manipulation; calling RemovePage during an in-flight Pop; navigation triggered from multiple threads; handler/renderer version mismatches after an upgrade.
Related errors
- ParentingViewController parent could not be found. Please fi
- 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
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/6d05cfa9713cc5ca.
Report an issue: GitHub.