angular/components · error

The URL provided to MatIconRegistry was not trusted as a…

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.

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.

Appendix: 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)