fabricjs/fabric.js · error · FabricError
Resource '${url}' is not allowed
Error message
Resource '${url}' is not allowed What it means
Thrown by loadImage in objectEnlive when a configured resourceValidator rejects the URL being loaded. It is a security feature (SSRF/XSS protection): when a resourceValidator function is set in config, every image URL must be approved by it before loading. The message names the exact URL that was denied.
Source
Thrown at packages/core/src/util/misc/objectEnlive.ts:41
/**
* Loads image element from given url and resolve it, or catch.
* @param {String} url URL representing an image
* @param {LoadImageOptions} [options] image loading options
* @returns {Promise<HTMLImageElement>} the loaded image.
*/
export const loadImage = (
url: string,
{ signal, crossOrigin = null, resourceValidator }: LoadImageOptions = {},
): Promise<HTMLImageElement> => {
if (signal && signal.aborted) {
return Promise.reject(new SignalAbortedError('loadImage'));
}
if (url && resourceValidator) {
return Promise.resolve()
.then(() => resourceValidator(url))
.then((isAllowed) => {
if (!isAllowed) {
throw new FabricError(`Resource '${url}' is not allowed`);
}
if (signal && signal.aborted) {
throw new SignalAbortedError('loadImage');
}
return loadImage(url, { signal, crossOrigin });
});
}
return new Promise<HTMLImageElement>(function (resolve, reject) {
if (signal && signal.aborted) {
return reject(new SignalAbortedError('loadImage'));
}
const img = createImage();
let abort: EventListenerOrEventListenerObject;
if (signal) {
abort = function (err: Event) {
img.src = '';
reject(err);
};View on GitHub (pinned to 2bd4992cab)
Solutions
- Inspect the URL in the message and update the resourceValidator to allow it if it is trusted (e.g. add the host to an allowlist)
- If the URL is untrusted, sanitize the stored JSON data to use safe/rewritten URLs instead of relaxing the validator
- Fix a validator that accidentally returns undefined/falsy for valid URLs (make sure it resolves boolean true)
- If intentional denial, catch the error and handle the missing image gracefully (placeholder)
Example fix
// before
import { config } from 'fabric';
config.resourceValidator = (url) => new URL(url, location.href).origin === location.origin;
// loading an external image throws: Resource 'https://cdn.example.com/a.png' is not allowed
// after
config.resourceValidator = (url) => {
const u = new URL(url, location.href);
return u.origin === location.origin || u.hostname === 'cdn.example.com';
}; Defensive patterns
Strategy: validation
Validate before calling
import { config } from 'fabric';
const isAllowed = config.resourceValidator
? await config.resourceValidator(url)
: true;
if (!isAllowed) {
// rewrite/skip the URL before loading
} Type guard
const isSafeUrl = (url: string): boolean => {
try {
const u = new URL(url, location.href);
return u.protocol === 'https:' && ALLOWED_HOSTS.has(u.hostname);
} catch { return false; }
}; Try / catch
try {
const img = await fabric.loadImage(url, { crossOrigin: 'anonymous' });
} catch (e) {
if (e instanceof Error && e.message.startsWith("Resource '")) {
// URL rejected by validator: use placeholder or rewrite URL
} else throw e;
} Prevention
- Keep an explicit URL allowlist and sanitize saved JSON before loadFromJSON
- Make resourceValidator return an explicit boolean
- Log rejected URLs to catch legacy data with unsafe URLs early
- Test loading old saved canvases after adding a validator
When it happens
Trigger: Calling fabric.loadImage / enlivenObjects (fromJSON) with an image URL while config.resourceValidator is set and returns false (or a falsy value) for that URL, e.g. only allowing https:// or same-origin URLs but the object contains http:// or a data: URL.
Common situations: Apps that added a resourceValidator for security and then load older saved JSONs containing external http URLs, relative URLs, or data URIs; or a validator with a bug (returning undefined instead of true) causing every image to be rejected.
Related errors
AI-assisted analysis of fabricjs/fabric.js@2bd4992cab (2026-08-28).
Data as JSON: /api/errors/ec1c12e664572f3e.
Report an issue: GitHub.