dotnet/machinelearning · error · NotSupportedException
The function ResourceManagerUtils.EnsureResourceAsync only s
Error message
The function ResourceManagerUtils.EnsureResourceAsync only supports downloading from URLs of the host "aka.ms"
What it means
ResourceManagerUtils.EnsureResourceAsync downloads ML.NET resources (e.g. image-model pretrained models) from a known base URL, then only permits downloads whose resolved absolute host is exactly "aka.ms". Any other host throws NotSupportedException because Microsoft restricts this code path to its own trusted short-link domain, both for security (avoiding arbitrary downloads) and licensing. This is an intentional allowlist, not a bug.
Source
Thrown at src/Microsoft.ML.Core/Utilities/ResourceManagerUtils.cs:120
/// <param name="fileName">The name of the file to save.</param>
/// <param name="dir">The directory where the file should be saved to. The file will be saved in a directory with the specified name inside
/// a folder called "mlnet-resources" in the <see cref="Environment.SpecialFolder.ApplicationData"/> directory.</param>
/// <param name="timeout">An integer indicating the number of milliseconds to wait before timing out while downloading a resource.</param>
/// <returns>The download results, containing the file path where the resources was (or should have been) downloaded to, and an error message
/// (or null if there was no error).</returns>
public async Task<ResourceDownloadResults> EnsureResourceAsync(IHostEnvironment env, IChannel ch, string relativeUrl, string fileName, string dir, int timeout)
{
var filePath = GetFilePath(ch, fileName, dir, out var error);
if (File.Exists(filePath) || !string.IsNullOrEmpty(error))
return new ResourceDownloadResults(filePath, error);
if (!Uri.TryCreate(Path.Combine(MlNetResourcesUrl, relativeUrl), UriKind.Absolute, out var absoluteUrl))
{
return new ResourceDownloadResults(filePath,
$"Could not create a valid URI from the base URI '{MlNetResourcesUrl}' and the relative URI '{relativeUrl}'");
}
if (absoluteUrl.Host != "aka.ms")
throw new NotSupportedException("The function ResourceManagerUtils.EnsureResourceAsync only supports downloading from URLs of the host \"aka.ms\"");
return new ResourceDownloadResults(filePath,
await DownloadFromUrlWithRetryAsync(env, ch, absoluteUrl.AbsoluteUri, fileName, timeout, filePath), absoluteUrl.AbsoluteUri);
}
private async Task<string> DownloadFromUrlWithRetryAsync(IHostEnvironment env, IChannel ch, string url, string fileName,
int timeout, string filePath, int retryTimes = 5)
{
var downloadResult = "";
for (int i = 0; i < retryTimes; ++i)
{
try
{
var thisDownloadResult = await DownloadFromUrlAsync(env, ch, url, fileName, timeout, filePath);
if (string.IsNullOrEmpty(thisDownloadResult))
return thisDownloadResult;
elseView on GitHub (pinned to 7b76e69cf9)
Solutions
- Use only URLs whose final absolute host is "aka.ms"; revert any customization of the resources base URL to the default Microsoft endpoint.
- If you need resources from another host, download the file yourself (e.g. with HttpClient) and register/place it in the expected local cache path instead of using EnsureResourceAsync.
- Check the composed URL: combine MlNetResourcesUrl with relativeUrl using Uri.TryCreate and inspect .Host before calling, so you know what the method will see.
Example fix
// before
var results = await ResourceManagerUtils.Instance.EnsureResourceAsync(env, ch,
"https://example.com/models/model.res", "model.res", timeout);
// after
if (new Uri(modelUrl).Host == "aka.ms")
{
var results = await ResourceManagerUtils.Instance.EnsureResourceAsync(env, ch,
modelUrl, "model.res", timeout);
}
else
{
// download manually and place the file in the expected cache location
await DownloadToCacheAsync(modelUrl, cachePath);
} Defensive patterns
Strategy: validation
Validate before calling
if (Uri.TryCreate(Path.Combine(MlNetResourcesUrl, relativeUrl), UriKind.Absolute, out var abs)
&& abs.Host == "aka.ms")
{
await ResourceManagerUtils.Instance.EnsureResourceAsync(env, ch, relativeUrl, fileName, timeout);
} Type guard
static bool IsAllowedResourceUrl(Uri url) => url?.Host == "aka.ms";
Try / catch
try
{
await ResourceManagerUtils.Instance.EnsureResourceAsync(env, ch, relativeUrl, fileName, timeout);
}
catch (NotSupportedException ex)
{
// non-aka.ms host: fall back to manual download or surface config error
} Prevention
- Do not override the resource base URL in production.
- Pre-resolve the composed URL and check Host before downloading.
- Download third-party resources manually instead of routing them through this method.
When it happens
Trigger: Calling ResourceManagerUtils.EnsureResourceAsync with a relativeUrl that resolves against MlNetResourcesUrl to a non-aka.ms host (e.g. after MlNetResourcesUrl was redirected, overridden for testing, or the relative path escaped the aka.ms domain via '../' segments).
Common situations: Enterprise environments redirecting aka.ms through a proxy/mirror domain; developers pointing the resource manager at a custom mirror to work offline; test setups substituting a local base URL; DNS/CDN changes causing aka.ms short links to resolve under a different host string.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- The provided url ({uri}) redirects to the default url ({Defa
- Strings.ImmutableColumn
- null
- TKey
- Type is T
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/c7231bf9555e6470.
Report an issue: GitHub.