{"record":{"id":"81b0eb5d260d2673","repo":"nexu-io/open-design","slug":"cloudflare-zone-not-full","errorCode":"cloudflare_zone_not_full","errorMessage":"Cloudflare custom domains require a full DNS zone.","messagePattern":"Cloudflare custom domains require a full DNS zone\\.","errorType":"http","errorClass":"DeployError","httpStatus":400,"severity":"error","filePath":"apps/daemon/src/deploy.ts","lineNumber":611,"sourceCode":"  });\n  const json = await readCloudflareJson(resp);\n  if (!resp.ok || json?.success === false) {\n    throw cloudflareError(json, resp.status, 'Cloudflare zone lookup failed.');\n  }\n  const zone = json?.result ?? json;\n  const zoneName = normalizeCloudflareZoneName(zone?.name);\n  if (!zoneName || zoneName !== selection.zoneName) {\n    throw new DeployError('Cloudflare zone selection no longer matches the selected domain.', 400, {\n      errorCode: 'cloudflare_zone_mismatch',\n    });\n  }\n  if (zone?.status && zone.status !== 'active') {\n    throw new DeployError('Cloudflare custom domains require an active zone.', 400, {\n      errorCode: 'cloudflare_zone_inactive',\n    });\n  }\n  if (zone?.type && zone.type !== 'full') {\n    throw new DeployError('Cloudflare custom domains require a full DNS zone.', 400, {\n      errorCode: 'cloudflare_zone_not_full',\n    });\n  }\n  return { ...selection, zoneName };\n}\n\nasync function setupCloudflarePagesCustomDomain({ config, projectId, selection, pagesDevUrl, priorMetadata }: { config: DeployConfig; projectId: string; selection: CloudflarePagesDeploySelection; pagesDevUrl: string; priorMetadata?: JsonObject | undefined }) {\n  if (!config.projectName) throw new DeployError('Cloudflare Pages project name could not be generated.', 400);\n  const pagesTarget = normalizeHostname(hostnameFromUrl(pagesDevUrl) || `${config.projectName}.pages.dev`);\n  const marker = cloudflarePagesDnsMarker(projectId, config.projectName, pagesTarget);\n  const base = {\n    hostname: selection.hostname,\n    url: `https://${selection.hostname}`,\n    zoneId: selection.zoneId,\n    zoneName: selection.zoneName,\n    domainPrefix: selection.domainPrefix,\n  };\n","sourceCodeStart":593,"sourceCodeEnd":629,"githubUrl":"https://github.com/nexu-io/open-design/blob/5be4028344c2eb4c667c5a97bda8f750c5597ef7/apps/daemon/src/deploy.ts#L593-L629","documentation":"Thrown by validateCloudflarePagesDeploySelection in apps/daemon/src/deploy.ts:611 as `DeployError('Cloudflare custom domains require a full DNS zone.', 400, { errorCode: 'cloudflare_zone_not_full' })` when the zone's `type` is present and not `'full'`. Cloudflare distinguishes `full` (nameserver setup, full DNS control) from `partial` (CNAME setup, limited). The custom-domain CNAME flow assumes full DNS authority, so partial zones are rejected.","triggerScenarios":"The selected zone matches by name and is active, but `zone.type === 'partial'` (CNAME setup). The user added the domain to Cloudflare via CNAME setup rather than changing nameservers.","commonSituations":"Domain is hosted elsewhere with Cloudflare used only as a CDN via CNAME setup; the zone was added in partial mode to avoid nameserver migration; org policy forbids full zones.","solutions":["Convert the zone to a full (nameserver) setup in Cloudflare so type becomes 'full'.","Alternatively, choose a different zone that is already full-setup, or skip the custom-domain option and use the default *.pages.dev URL."],"exampleFix":"null","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"function isZoneNotFull(err: unknown): boolean {\n  return err instanceof DeployError && err.status === 400\n    && (err as any).details?.errorCode === 'cloudflare_zone_not_full';\n}","tryCatchPattern":"try {\n  await deployToCloudflarePages({ config, files, projectId, cloudflarePages: selection });\n} catch (err) {\n  if (isZoneNotFull(err)) {\n    return res.status(400).json({\n      error: 'This zone uses CNAME (partial) setup. Use a full-setup zone or the default *.pages.dev URL.',\n      errorCode: 'cloudflare_zone_not_full',\n    });\n  }\n  throw err;\n}","preventionTips":["In the zone picker, only offer zones whose type is 'full'.","If the org uses partial zones, fall back to the default pages.dev hostname instead of a custom domain.","Document that custom domains require full (nameserver) Cloudflare setup."],"tags":["deploy","cloudflare","custom-domain","zone","dns"],"backgroundTag":null,"analyzedSha":"5be4028344c2eb4c667c5a97bda8f750c5597ef7","analyzedAt":"2026-08-12T12:03:58.812Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}