{"record":{"id":"c85960cacc2e98df","repo":"nextauthjs/next-auth","slug":"option-domain-is-invalid-options-domain","errorCode":null,"errorMessage":"option domain is invalid: ${options.domain}","messagePattern":"option domain is invalid: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/lib/vendored/cookie.ts","lineNumber":284,"sourceCode":"\n  if (!cookieValueRegExp.test(value)) {\n    throw new TypeError(`argument val is invalid: ${val}`)\n  }\n\n  let str = name + \"=\" + value\n  if (!options) return str\n\n  if (options.maxAge !== undefined) {\n    if (!Number.isInteger(options.maxAge)) {\n      throw new TypeError(`option maxAge is invalid: ${options.maxAge}`)\n    }\n\n    str += \"; Max-Age=\" + options.maxAge\n  }\n\n  if (options.domain) {\n    if (!domainValueRegExp.test(options.domain)) {\n      throw new TypeError(`option domain is invalid: ${options.domain}`)\n    }\n\n    str += \"; Domain=\" + options.domain\n  }\n\n  if (options.path) {\n    if (!pathValueRegExp.test(options.path)) {\n      throw new TypeError(`option path is invalid: ${options.path}`)\n    }\n\n    str += \"; Path=\" + options.path\n  }\n\n  if (options.expires) {\n    if (\n      !isDate(options.expires) ||\n      !Number.isFinite(options.expires.valueOf())\n    ) {","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/nextauthjs/next-auth/blob/a1a16a5a7780488c7449feece410033f445d0b31/packages/core/src/lib/vendored/cookie.ts#L266-L302","documentation":"serialize() validates the optional `domain` option against domainValueRegExp before appending `; Domain=` to the Set-Cookie string. If the value is present but not a syntactically valid domain attribute (e.g. contains illegal characters, spaces, or an invalid form), a TypeError is thrown immediately. This is a fail-fast guard so malformed cookie attributes never reach the browser.","triggerScenarios":"Calling serialize(name, val, { domain: 'not a domain!' }) or any domain containing characters outside the allowed domain-value pattern — e.g. trailing dots/slashes, underscores, spaces, full URLs like 'https://example.com', or an empty-but-truthy invalid string.","commonSituations":"Reading the domain from an env var or config that holds a full URL instead of a bare hostname; concatenating a port ('example.com:3000' — ports are not allowed in cookie domains); user-supplied input passed through unvalidated; typos like 'exam ple.com'.","solutions":["Pass only the bare hostname, e.g. domain: 'example.com' (leading dot is allowed but unnecessary for host-only matching)","Strip protocol/path/port: new URL(configuredDomain).hostname","Validate with a regex before calling serialize","If the domain is dynamic/user-supplied, reject invalid values upstream instead of letting serialize throw"],"exampleFix":"// before\nserialize('sid', val, { domain: process.env.COOKIE_DOMAIN }) // 'https://example.com'\n// after\nconst { hostname } = new URL(process.env.COOKIE_DOMAIN)\nserialize('sid', val, { domain: hostname })","handlingStrategy":"validation","validationCode":"function isValidCookieDomain(d) {\n  return typeof d === 'string' && /^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*$/.test(d.replace(/^\\./, ''))\n}\nif (opts.domain && !isValidCookieDomain(opts.domain)) throw new TypeError(`option domain is invalid: ${opts.domain}`)","typeGuard":"function isCookieDomain(v: unknown): v is string {\n  return typeof v === 'string' && v.length > 0 && !/[^a-zA-Z0-9.\\-]/.test(v)\n}","tryCatchPattern":"let cookie\ntry {\n  cookie = serialize('sid', val, { domain })\n} catch (err) {\n  if (err instanceof TypeError && err.message.startsWith('option domain is invalid')) {\n    throw new ConfigError(`Bad COOKIE_DOMAIN '${domain}' — use a bare hostname, not a URL`)\n  }\n  throw err\n}","preventionTips":["Always pass a bare hostname, never a URL or host:port","Derive the domain with new URL(input).hostname when sourcing from config","Validate env/config values at application startup, not at request time","Unit-test serialize calls with every configurable cookie option"],"tags":["cookie","validation","typeerror","serialize"],"backgroundTag":"invalid-cookie-attribute","analyzedSha":"a1a16a5a7780488c7449feece410033f445d0b31","analyzedAt":"2026-08-28T21:52:38.200Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}