gethomepage/homepage · critical · Error

Homepage auth is enabled but HOMEPAGE_EXTERNAL_URL (or NEXTA

Error message

Homepage auth is enabled but HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) is missing.

What it means

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.

Source

Thrown at src/pages/api/auth/[...nextauth].js:38

  : null;

// Map HOMEPAGE_* envs to what NextAuth expects
if (!process.env.NEXTAUTH_SECRET && homepageAuthSecret) {
  process.env.NEXTAUTH_SECRET = homepageAuthSecret;
}
if (!process.env.NEXTAUTH_URL && homepageExternalUrl) {
  process.env.NEXTAUTH_URL = homepageExternalUrl;
}

const defaultScope = process.env.HOMEPAGE_OIDC_SCOPE || "openid email profile";
const cleanedIssuer = issuer ? issuer.replace(/\/+$/, "") : issuer;
const hasOidcConfig = Boolean(issuer && clientId && clientSecret);
const hasAnyOidcConfig = Boolean(issuer || clientId || clientSecret);
let parsedAuthUrl;

if (authEnabled) {
  if (!process.env.NEXTAUTH_URL) {
    throw new Error("Homepage auth is enabled but HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) is missing.");
  }

  try {
    parsedAuthUrl = new URL(process.env.NEXTAUTH_URL);
  } catch {
    throw new Error("HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) must be an absolute HTTP(S) URL.");
  }

  if (
    !["http:", "https:"].includes(parsedAuthUrl.protocol) ||
    parsedAuthUrl.username ||
    parsedAuthUrl.password ||
    parsedAuthUrl.search ||
    parsedAuthUrl.hash
  ) {
    throw new Error(
      "HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) must be an absolute HTTP(S) URL without credentials, query, or fragment.",
    );

View on GitHub (pinned to b6dca1ae03)

Solutions

  1. Set HOMEPAGE_EXTERNAL_URL to the externally reachable HTTPS URL (e.g. https://home.example.com) in your env/docker-compose.
  2. Alternatively set NEXTAUTH_URL directly to the same absolute URL.
  3. If auth is not actually needed, disable it by removing/unsetting HOMEPAGE_AUTH_ENABLED.
  4. Restart the container/process so the NextAuth module re-evaluates env at load time.

Example fix

// before
HOMEPAGE_AUTH_ENABLED=true
# no URL set

// after (docker-compose)
environment:
  HOMEPAGE_AUTH_ENABLED: "true"
  HOMEPAGE_EXTERNAL_URL: "https://home.example.com"
Defensive patterns

Strategy: validation

Validate before calling

function validateAuthEnv(env) {
  const errors = [];
  if (env.HOMEPAGE_AUTH_ENABLED === 'true') {
    const url = env.NEXTAUTH_URL || env.HOMEPAGE_EXTERNAL_URL;
    if (!url) errors.push('Set HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) to an absolute HTTPS URL.');
  }
  return errors;
}
// run before boot:
const issues = validateAuthEnv(process.env);
if (issues.length) { console.error(issues); process.exit(1); }

Prevention

When it happens

Trigger: 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 ... }`.

Common situations: 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.

Related errors


AI-assisted analysis of gethomepage/homepage@b6dca1ae03 (2026-08-13). Data as JSON: /api/errors/3977c1444d229202. Report an issue: GitHub.