angular/components · error

The URL provided to MatIconRegistry was not trusted as a res

Error message

The URL provided to MatIconRegistry was not trusted as a resource URL via Angular's DomSanitizer. Attempted URL was "${safeUrl}".

What it means

getSvgIconFromUrl sanitizes the provided SafeResourceUrl through DomSanitizer's RESOURCE_URL context before fetching. If the URL wasn't trusted via bypassSecurityTrustResourceUrl (or sanitization yields empty), the registry throws this error rather than requesting an unsafe resource.

Source

Thrown at src/material/icon/icon-registry.ts:343

   * have a fontSet input value, and is not loading an icon by name or URL.
   */
  getDefaultFontSetClass(): string[] {
    return this._defaultFontSetClass;
  }

  /**
   * Returns an Observable that produces the icon (as an `<svg>` DOM element) from the given URL.
   * The response from the URL may be cached so this will not always cause an HTTP request, but
   * the produced element will always be a new copy of the originally fetched icon. (That is,
   * it will not contain any modifications made to elements previously returned).
   *
   * @param safeUrl URL from which to fetch the SVG icon.
   */
  getSvgIconFromUrl(safeUrl: SafeResourceUrl): Observable<SVGElement> {
    const url = this._sanitizer.sanitize(SecurityContext.RESOURCE_URL, safeUrl);

    if (!url) {
      throw getMatIconFailedToSanitizeUrlError(safeUrl);
    }

    const cachedIcon = this._cachedIconsByUrl.get(url);

    if (cachedIcon) {
      return observableOf(cloneSvg(cachedIcon));
    }

    return this._loadSvgIconFromConfig(new SvgIconConfig(safeUrl, null)).pipe(
      tap(svg => this._cachedIconsByUrl.set(url!, svg)),
      map(svg => cloneSvg(svg)),
    );
  }

  /**
   * Returns an Observable that produces the icon (as an `<svg>` DOM element) with the given name
   * and namespace. The icon must have been previously registered with addIcon or addIconSet;
   * if not, the Observable will throw an error.

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Trust the URL once: sanitizer.bypassSecurityTrustResourceUrl(url) before passing it.
  2. Better: register icons via addSvgIcon / addSvgIconSet with trusted URLs at bootstrap instead of ad-hoc getSvgIconFromUrl calls.
  3. UseDomSanitizer injection: constructor(private sanitizer: DomSanitizer) and wrap where the URL is created, not where consumed.
  4. Verify the value isn't empty/undefined — a falsy URL also fails sanitization and throws the same error.

Example fix

// before
this.registry.getSvgIconFromUrl(iconUrl as any);
// after
const safeUrl = this.sanitizer.bypassSecurityTrustResourceUrl(iconUrl);
this.registry.getSvgIconFromUrl(safeUrl);
Defensive patterns

Strategy: type-guard

Validate before calling

import { SafeResourceUrl } from '@angular/platform-browser';
function isTrustedResourceUrl(v: unknown): v is SafeResourceUrl {
  return typeof v === 'object' && v !== null && 'changingThisBreaksApplicationSecurity' in v;
}
if (!isTrustedResourceUrl(url)) url = sanitizer.bypassSecurityTrustResourceUrl(String(url));

Type guard

function isSafeResourceUrl(v: unknown): v is SafeResourceUrl {
  return !!v && typeof v === 'object' &&
    typeof (v as any).changingThisBreaksApplicationSecurity === 'string';
}

Try / catch

try {
  await registry.getSvgIconFromUrl(safeUrl).toPromise();
} catch (e) {
  if (e instanceof Error && e.message.includes('not trusted as a resource URL')) {
    console.error('Trust the URL with bypassSecurityTrustResourceUrl before use.');
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling registry.getSvgIconFromUrl(this.someUrl) with a plain string cast as SafeResourceUrl, or a URL never passed through sanitizer.bypassSecurityTrustResourceUrl; also when a bound/interpolated URL string is handed to addSvgIconInNamespace paths that fetch by URL.

Common situations: Loading icons from a CDN or assets host without registering the domain; Angular strict template checking absent so string sneaks into SafeResourceUrl position; migration to Angular's stricter security defaults making previously 'working' raw-string URLs throw.

Related errors


AI-assisted analysis of angular/components@0411926e7d (2026-08-31). Data as JSON: /api/errors/c9a171e525e5a6a9. Report an issue: GitHub.