dotnet/maui · error · ArgumentException

Invalid Uri

Error message

Invalid Uri

What it means

Thrown by Platform.ResolveMsAppDataUri when the URI uses the ms-appdata scheme but its LocalPath does not start with /local or /temp. The resolver only supports two ms-appdata sub-paths: /local (mapped to the app's MyDocuments) and /temp (mapped to the system temp directory). Any other path (e.g., /roaming, /cache) is rejected.

Source

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

		}

		internal static string ResolveMsAppDataUri(Uri uri)
		{
			if (uri.Scheme == "ms-appdata")
			{
				string filePath = string.Empty;

				if (uri.LocalPath.StartsWith("/local"))
				{
					filePath = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments), uri.LocalPath.Substring(7));
				}
				else if (uri.LocalPath.StartsWith("/temp"))
				{
					filePath = System.IO.Path.Combine(System.IO.Path.GetTempPath(), uri.LocalPath.Substring(6));
				}
				else
				{
					throw new ArgumentException("Invalid Uri", "Source");
				}

				return filePath;
			}
			else
			{
				throw new ArgumentException("uri");
			}

		}
	}
}

View on GitHub (pinned to f377ff1c5e)

Solutions

  1. Use only ms-appdata:///local/... or ms-appdata:///temp/... paths on Android.
  2. For roaming-equivalent data, use a file in the local path and sync via a custom mechanism, or use a non-ms-appdata file URI.
  3. Validate the URI path before passing it to the image/file source; surface a friendly error if the path is unsupported.

Example fix

// before
var uri = new Uri("ms-appdata:///roaming/settings.json");
var path = Platform.ResolveMsAppDataUri(uri); // throws

// after
var uri = new Uri("ms-appdata:///local/settings.json");
var path = Platform.ResolveMsAppDataUri(uri);
Defensive patterns

Strategy: validation

Validate before calling

// Validate the ms-appdata path is supported before resolving.
static bool IsValidMsAppDataPath(Uri uri)
{
    return uri.Scheme == "ms-appdata"
        && (uri.LocalPath.StartsWith("/local") || uri.LocalPath.StartsWith("/temp"));
}

Prevention

When it happens

Trigger: Supplying an ms-appdata URI with an unsupported path segment such as ms-appdata:///roaming/file.json or ms-appdata:///cache/data.db. The resolver parses the scheme correctly but the LocalPath branch falls through to the else clause.

Common situations: Porting a UWP app that used ms-appdata:///local and adding a roaming path that Android does not support. Constructing ms-appdata URIs dynamically with a path variable that can take unsupported values. Misremembering the supported sub-paths.

Related errors


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