Dokploy/dokploy · error · Error

The base domain must start with "*."

Error message

The base domain must start with "*."

What it means

generateWildcardDomain requires the base domain argument to begin with the literal prefix "*." because it builds a wildcard DNS entry (e.g. *.example.com) for preview deployments. Any base domain missing that prefix cannot be used to generate per-preview subdomains. The check is a simple string startsWith guard before any hashing or DNS work.

Source

Thrown at packages/server/src/services/preview-deployment.ts:248

) => {
	const previewDeploymentResult = await db.query.previewDeployments.findFirst({
		where: and(
			eq(previewDeployments.applicationId, applicationId),
			eq(previewDeployments.pullRequestId, pullRequestId),
		),
	});

	return previewDeploymentResult;
};

const generateWildcardDomain = async (
	baseDomain: string,
	appName: string,
	serverIp: string,
	_userId: string,
): Promise<string> => {
	if (!baseDomain.startsWith("*.")) {
		throw new Error('The base domain must start with "*."');
	}
	const hash = `${appName}`;
	if (baseDomain.includes("sslip.io")) {
		let ip = "";

		if (process.env.NODE_ENV === "development") {
			ip = "127.0.0.1";
		}

		if (serverIp) {
			ip = serverIp;
		}

		if (!ip) {
			const settings = await getWebServerSettings();
			ip = settings?.serverIp || "";
		}

View on GitHub (pinned to 546686ea35)

Solutions

  1. Set the base domain to include the wildcard prefix, e.g. change "example.com" to "*.example.com" in the preview/deployment domain settings that feed this call
  2. If using sslip.io-style domains, pass "*.<ip>.sslip.io" so the wildcard check passes and the IP-substitution branch can run
  3. Add upfront validation in the settings UI/API so the base domain must match /^\*\./ before persisting

Example fix

// before
const domain = await generateWildcardDomain("mysite.com", appName, ip, userId);
// after
const domain = await generateWildcardDomain("*.mysite.com", appName, ip, userId);
Defensive patterns

Strategy: validation

Validate before calling

const isValidBaseDomain = (d: string) => /^\*\.[a-z0-9.-]+$/i.test(d.trim());
if (!isValidBaseDomain(baseDomain)) throw new Error('base domain must look like *.example.com');

Type guard

const isWildcardDomain = (d: string): d is `*.${string}` => d.startsWith('*.');

Try / catch

try { await generateDomain(base, ...) } catch (e) { if (e instanceof Error && e.message.includes('must start with')) { /* re-prompt for *.domain */ } }

Prevention

When it happens

Trigger: Calling generateDomain/generateWildcardDomain (preview deployment domain generation) with a base domain like "example.com" or "sslip.io" instead of "*.example.com". Typically the value comes from server settings or an env-configured base domain field.

Common situations: Admin configured the preview-deployment base domain in server settings without the wildcard prefix; migrated config from a non-wildcard setup; typo like "*." vs "*"; using a bare sslip.io domain without the leading "*.".

Related errors


AI-assisted analysis of Dokploy/dokploy@546686ea35 (2026-08-27). Data as JSON: /api/errors/1563bfdb97f8fccc. Report an issue: GitHub.