{"record":{"id":"3977c1444d229202","repo":"gethomepage/homepage","slug":"homepage-auth-is-enabled-but-homepage-external-url","errorCode":null,"errorMessage":"Homepage auth is enabled but HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) is missing.","messagePattern":"Homepage auth is enabled but HOMEPAGE_EXTERNAL_URL \\(or NEXTAUTH_URL\\) is missing\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/pages/api/auth/[...nextauth].js","lineNumber":38,"sourceCode":"  : null;\n\n// Map HOMEPAGE_* envs to what NextAuth expects\nif (!process.env.NEXTAUTH_SECRET && homepageAuthSecret) {\n  process.env.NEXTAUTH_SECRET = homepageAuthSecret;\n}\nif (!process.env.NEXTAUTH_URL && homepageExternalUrl) {\n  process.env.NEXTAUTH_URL = homepageExternalUrl;\n}\n\nconst defaultScope = process.env.HOMEPAGE_OIDC_SCOPE || \"openid email profile\";\nconst cleanedIssuer = issuer ? issuer.replace(/\\/+$/, \"\") : issuer;\nconst hasOidcConfig = Boolean(issuer && clientId && clientSecret);\nconst hasAnyOidcConfig = Boolean(issuer || clientId || clientSecret);\nlet parsedAuthUrl;\n\nif (authEnabled) {\n  if (!process.env.NEXTAUTH_URL) {\n    throw new Error(\"Homepage auth is enabled but HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) is missing.\");\n  }\n\n  try {\n    parsedAuthUrl = new URL(process.env.NEXTAUTH_URL);\n  } catch {\n    throw new Error(\"HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) must be an absolute HTTP(S) URL.\");\n  }\n\n  if (\n    ![\"http:\", \"https:\"].includes(parsedAuthUrl.protocol) ||\n    parsedAuthUrl.username ||\n    parsedAuthUrl.password ||\n    parsedAuthUrl.search ||\n    parsedAuthUrl.hash\n  ) {\n    throw new Error(\n      \"HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) must be an absolute HTTP(S) URL without credentials, query, or fragment.\",\n    );","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/gethomepage/homepage/blob/b6dca1ae033e613d8e692f9a161a3cc53a5a2857/src/pages/api/auth/[...nextauth].js#L20-L56","documentation":"Thrown at module load of the NextAuth route when Homepage's built-in authentication is enabled but the server has no base URL to anchor auth redirects against. Homepage copies HOMEPAGE_EXTERNAL_URL into NEXTAUTH_URL first, so this fires only when BOTH are unset. Without it NextAuth cannot build callback URLs or sign JWTs correctly.","triggerScenarios":"HOMEPAGE_AUTH_ENABLED=true (or the settings.yaml equivalent) and neither process.env.NEXTAUTH_URL nor process.env.HOMEPAGE_EXTERNAL_URL is set when src/pages/api/auth/[...nextauth].js is first imported. The guard is `if (authEnabled) { if (!process.env.NEXTAUTH_URL) throw ... }`.","commonSituations":"Fresh docker-compose deploy where the operator set HOMEPAGE_AUTH_ENABLED but forgot HOMEPAGE_EXTERNAL_URL; running behind a reverse proxy with only an internal port mapped; CI/test environment that enables auth via settings.yaml without exporting the URL.","solutions":["Set HOMEPAGE_EXTERNAL_URL to the externally reachable HTTPS URL (e.g. https://home.example.com) in your env/docker-compose.","Alternatively set NEXTAUTH_URL directly to the same absolute URL.","If auth is not actually needed, disable it by removing/unsetting HOMEPAGE_AUTH_ENABLED.","Restart the container/process so the NextAuth module re-evaluates env at load time."],"exampleFix":"// before\nHOMEPAGE_AUTH_ENABLED=true\n# no URL set\n\n// after (docker-compose)\nenvironment:\n  HOMEPAGE_AUTH_ENABLED: \"true\"\n  HOMEPAGE_EXTERNAL_URL: \"https://home.example.com\"","handlingStrategy":"validation","validationCode":"function validateAuthEnv(env) {\n  const errors = [];\n  if (env.HOMEPAGE_AUTH_ENABLED === 'true') {\n    const url = env.NEXTAUTH_URL || env.HOMEPAGE_EXTERNAL_URL;\n    if (!url) errors.push('Set HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) to an absolute HTTPS URL.');\n  }\n  return errors;\n}\n// run before boot:\nconst issues = validateAuthEnv(process.env);\nif (issues.length) { console.error(issues); process.exit(1); }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep a single env checklist for auth: HOMEPAGE_AUTH_ENABLED + HOMEPAGE_EXTERNAL_URL + NEXTAUTH_SECRET (+ password or OIDC triple).","Use a startup preflight script that fails fast on missing required env.","Store the external URL in one variable and let it flow to NEXTAUTH_URL to avoid drift.","Smoke-test the /api/auth endpoint after deploy."],"tags":["auth","configuration","env","nextauth","startup"],"backgroundTag":null,"analyzedSha":"b6dca1ae033e613d8e692f9a161a3cc53a5a2857","analyzedAt":"2026-08-13T04:48:44.121Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}