dotnet/maui · error · InvalidOperationException

PushAsync is not supported globally on Android, please use a

Error message

PushAsync is not supported globally on Android, please use a NavigationPage.

What it means

Thrown by the Platform class's explicit INavigation.PushAsync(bool) implementation. On Android, the global platform does not support non-modal page pushes; PushAsync requires a NavigationPage. Only PushModalAsync is available at the platform level.

Source

Thrown at src/Compatibility/Core/src/Android/AppCompat/Platform.cs:192

		Task INavigation.PopToRootAsync()
		{
			return ((INavigation)this).PopToRootAsync(true);
		}

		Task INavigation.PopToRootAsync(bool animated)
		{
			throw new InvalidOperationException("PopToRootAsync is not supported globally on Android, please use a NavigationPage.");
		}

		Task INavigation.PushAsync(Page root)
		{
			return ((INavigation)this).PushAsync(root, true);
		}

		Task INavigation.PushAsync(Page root, bool animated)
		{
			throw new InvalidOperationException("PushAsync is not supported globally on Android, please use a NavigationPage.");
		}

		Task INavigation.PushModalAsync(Page modal)
		{
			return ((INavigation)this).PushModalAsync(modal, true);
		}

		async Task INavigation.PushModalAsync(Page modal, bool animated)
		{
			CurrentPageController?.SendDisappearing();
			UpdateAccessibilityImportance(CurrentPageController as Page, ImportantForAccessibility.NoHideDescendants, false);

			_navModel.PushModal(modal);

			Task presentModal = PresentModal(modal, animated);

			await presentModal;

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Set MainPage to a NavigationPage (e.g., new NavigationPage(new MainPage())) so PushAsync works.
  2. Use PushModalAsync if a modal presentation is acceptable.
  3. In shared navigation services, detect the platform or check for a NavigationPage before choosing PushAsync vs PushModalAsync.

Example fix

// before
Application.Current.MainPage = new MainPage();
await Application.Current.MainPage.Navigation.PushAsync(new DetailPage()); // throws on Android

// after
Application.Current.MainPage = new NavigationPage(new MainPage());
await Application.Current.MainPage.Navigation.PushAsync(new DetailPage());
Defensive patterns

Strategy: validation

Validate before calling

// Ensure a NavigationPage root before PushAsync.
if (!(Application.Current.MainPage is NavigationPage))
    Application.Current.MainPage = new NavigationPage(Application.Current.MainPage);
await Application.Current.MainPage.Navigation.PushAsync(newPage);

Type guard

static bool CanPushAsync(Page root) => root is NavigationPage;

Prevention

When it happens

Trigger: Calling await Application.Current.MainPage.Navigation.PushAsync(page) on Android when MainPage is not a NavigationPage. This is the most commonly hit navigation error when porting iOS-first apps to Android.

Common situations: Shared MVVM navigation code that calls Navigation.PushAsync from a ViewModel without ensuring a NavigationPage root. Sample/template apps that omit NavigationPage.

Related errors


AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13). Data as JSON: /api/errors/8a9c16077a012936. Report an issue: GitHub.