sindresorhus/got · error · Error

The `url` option must be relative when `allowAbsoluteUrls` i

Error message

The `url` option must be relative when `allowAbsoluteUrls` is false and `prefixUrl` is set

What it means

Thrown at source/core/options.ts:1049 by `assertRelativeUrlIfNeeded`. When `prefixUrl` is set and `allowAbsoluteUrls` is false (the new default in recent got versions), the per-call URL MUST be relative. The check detects any absolute URL form — `https://...`, scheme-relative `//...`, `http:`, and (when enabled) unix-socket protocols without leading slashes. If the URL would bypass prefixUrl by being absolute, got throws rather than silently letting the call hit a different host than the configured one.

Source

Thrown at source/core/options.ts:1049

	return result;
};

const assertRelativeUrlIfNeeded = (options: Options, url: string | URL): void => {
	if (!options.prefixUrl || options.allowAbsoluteUrls) {
		return;
	}

	const normalizedUrl = is.string(url) ? stripLeadingC0ControlOrSpace(removeAsciiTabOrNewline(url)) : url;

	const isDisallowed = isAbsoluteUrl(normalizedUrl)
		|| (is.string(normalizedUrl) && (
			hasHttpProtocolWithoutSlashes(normalizedUrl)
			|| startsWithSchemeRelativeSeparators(normalizedUrl)
			|| (options.enableUnixSockets && hasUnixProtocolWithoutSlashes(normalizedUrl))
		));

	if (isDisallowed) {
		throw new Error('The `url` option must be relative when `allowAbsoluteUrls` is false and `prefixUrl` is set');
	}
};

export const assertUrlHasSameOriginAsPrefixUrlIfNeeded = (options: Options, url: URL): void => {
	if (!options.prefixUrl || options.allowAbsoluteUrls) {
		return;
	}

	let prefixUrl: URL;

	try {
		prefixUrl = new URL(options.prefixUrl);
	} catch {
		return;
	}

	if (isSameOrigin(prefixUrl, url)) {
		return;

View on GitHub (pinned to e3924aa1e5)

Solutions

  1. Pass a relative path instead: `client('/users/1')` or `client('users/1')`.
  2. If you intentionally need absolute URLs on this instance, opt in via `got.extend({ prefixUrl, allowAbsoluteUrls: true })`.
  3. Use a separate non-prefixed got instance for absolute URLs to different hosts.

Example fix

// before
const api = got.extend({ prefixUrl: 'https://api.example.com' });
await api('https://api.example.com/users'); // throws

// after — relative path under prefix
const api = got.extend({ prefixUrl: 'https://api.example.com' });
await api('users'); // → https://api.example.com/users

// or explicitly allow absolute
const client = got.extend({ prefixUrl: 'https://api.example.com', allowAbsoluteUrls: true });
Defensive patterns

Strategy: validation

Validate before calling

function assertRelativeWhenPrefixed(prefixUrl, allowAbsoluteUrls, url) {
  if (!prefixUrl || allowAbsoluteUrls) return;
  if (typeof url !== 'string') return;
  if (/^https?:\/\//i.test(url) || url.startsWith('//')) {
    throw new Error('Pass a relative URL when prefixUrl is set, or set allowAbsoluteUrls: true');
  }
}
assertRelativeWhenPrefixed(client.defaults.options.prefixUrl, client.defaults.options.allowAbsoluteUrls, url);
await client(url);

Type guard

function isAbsoluteUrl(url: string | URL): boolean {
  if (url instanceof URL) return true;
  return /^[a-z][a-z0-9+.-]*:/i.test(url) || url.startsWith('//');
}

function isRelativeUrl(url: string | URL): boolean {
  return !isAbsoluteUrl(url);
}

Try / catch

try {
  await client(url);
} catch (error) {
  if (error instanceof Error && /url option must be relative when `allowAbsoluteUrls` is false/.test(error.message)) {
    // strip the origin if it matches prefixUrl, otherwise switch instances
    const stripped = url.replace(new URL(client.defaults.options.prefixUrl).origin, '');
    return client(stripped);
  }
  throw error;
}

Prevention

When it happens

Trigger: Calling `client('https://other-host/path')` on a got instance created with `got.extend({ prefixUrl: 'https://api.example.com' })` without opting into absolute URLs; passing `//cdn.example.com/asset` (scheme-relative); passing `http://localhost` while prefixUrl points at production.

Common situations: got v12→v13/v14 upgrade where `allowAbsoluteUrls` flipped to false; mixing absolute CDN URLs into a prefixed API client; copy-pasting a fully-qualified URL into a call site that previously took a path; security-hardened clients that intentionally disallow cross-origin jumps.

Related errors


AI-assisted analysis of sindresorhus/got@e3924aa1e5 (2026-08-03). Data as JSON: /data/errors/c41d43dca23a0a4c.json. Report an issue: GitHub.