MagicMirrorOrg/MagicMirror · error

CORS proxy is disabled

Error message

CORS proxy is disabled

What it means

The `/cors` proxy handler in js/server_functions.js:60 refuses to proxy when `global.config.cors` is set to the literal string `"disabled"`. It returns HTTP 403 with a JSON body `{ error: "CORS proxy is disabled" }` and logs that you must set `cors` to `allowAll` or `allowWhitelist`. The proxy exists so modules can fetch cross-origin resources (RSS, calendars, weather APIs) that lack CORS headers.

Source

Thrown at js/server_functions.js:60

		// Load the real value from the environment. Fallback to placeholder if missing.
		return process.env[secretName] || placeholder;
	});
}

/**
 * A method that forwards HTTP Get-methods to the internet to avoid CORS-errors.
 *
 * Example input request url: /cors?sendheaders=header1:value1,header2:value2&expectedheaders=header1,header2&url=http://www.test.com/path?param1=value1
 *
 * Only the url-param of the input request url is required. It must be the last parameter.
 * @param {Request} req - the request
 * @param {Response} res - the result
 * @returns {Promise<void>} A promise that resolves when the response is sent
 */
async function cors (req, res) {
	if (global.config.cors === "disabled") {
		Log.error("CORS is disabled, you need to enable it in `config.js` by setting `cors` to `allowAll` or `allowWhitelist`");
		return res.status(403).json({ error: "CORS proxy is disabled" });
	}
	let url;
	try {
		const urlRegEx = "url=(.+?)$";

		const match = new RegExp(urlRegEx, "g").exec(req.url);
		if (!match) {
			url = `invalid url: ${req.url}`;
			Log.error(url);
			return res.status(400).send(url);
		} else {
			url = match[1];
			if (typeof global.config !== "undefined") {
				if (config.hideConfigSecrets) {
					url = replaceSecretPlaceholder(url);
				}
			}

View on GitHub (pinned to 4b4a59534f)

Solutions

  1. Set `cors: 'allowAll'` in config.js if you accept unrestricted proxying, or `cors: 'allowWhitelist'` to restrict proxied hosts, then restart the mirror.
  2. If you intentionally keep the proxy disabled, reconfigure the failing module to fetch its resource without the `/cors` endpoint (enable CORS on the upstream server, or use a module option that calls the backend directly).
  3. Verify `global.config` is actually loaded from your config.js — check that config.js parses (no syntax errors) so your `cors` setting takes effect.
  4. Check the server log for the companion message 'CORS is disabled, you need to enable it in `config.js` ...' to confirm which config file was loaded.

Example fix

// before (config.js)
cors: 'disabled',
// after
cors: 'allowWhitelist', // or 'allowAll'
Defensive patterns

Strategy: validation

Validate before calling

// Before calling the proxy, confirm it is enabled on the server config:
async function proxyEnabled(baseUrl) {
  const probe = await fetch(`${baseUrl}/cors?url=https://example.com`, { method: 'GET' });
  const body = await probe.json().catch(() => ({}));
  return !(probe.status === 403 && body.error === 'CORS proxy is disabled');
}

Type guard

function isProxyDisabledResponse(body) {
  return typeof body === 'object' && body !== null && body.error === 'CORS proxy is disabled';
}

Try / catch

const res = await fetch(`/cors?url=${encodeURIComponent(target)}`);
if (res.status === 403) {
  const body = await res.json().catch(() => ({}));
  if (body.error === 'CORS proxy is disabled') {
    // fall back to direct fetch or instruct user to set cors: 'allowAll'|'allowWhitelist'
  }
  throw new Error(body.error ?? 'CORS proxy rejected the request');
}

Prevention

When it happens

Trigger: A module or client issues a request like `/cors?url=https://...` while `config.cors === 'disabled'` in config.js (or `global.config` was initialized with that value); the request never reaches the URL parsing/SSRF checks because the feature check runs first.

Common situations: A user upgrades MagicMirror and the newer default `cors: 'disabled'` breaks a module that relied on the proxy; a config template copies `cors: 'disabled'` from a hardened/security-focused setup; deploying behind nginx where someone disabled the proxy thinking the webserver handles CORS, while modules still call `/cors?...`.

Related errors


AI-assisted analysis of MagicMirrorOrg/MagicMirror@4b4a59534f (2026-08-31). Data as JSON: /api/errors/8e69f7c4143ae5a1. Report an issue: GitHub.