gethomepage/homepage · critical · Error

HOMEPAGE_AUTH_SECRET (or NEXTAUTH_SECRET) must be at least $

Error message

HOMEPAGE_AUTH_SECRET (or NEXTAUTH_SECRET) must be at least ${MIN_AUTH_SECRET_LENGTH} characters. Generate one with: openssl rand -base64 32

What it means

Thrown when NEXTAUTH_SECRET is present but shorter than MIN_AUTH_SECRET_LENGTH (32 characters). Short secrets are brute-forceable, so Homepage enforces a minimum entropy floor before allowing auth to start.

Source

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

    parsedAuthUrl.hash
  ) {
    throw new Error(
      "HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) must be an absolute HTTP(S) URL without credentials, query, or fragment.",
    );
  }

  if (hasOidcConfig) {
    if (!process.env.NEXTAUTH_SECRET) {
      throw new Error("OIDC auth is enabled but required settings are missing.");
    }
  } else if (hasAnyOidcConfig) {
    throw new Error("OIDC auth is enabled but required settings are missing.");
  } else if (!homepageAuthPassword || !process.env.NEXTAUTH_SECRET) {
    throw new Error("Password auth is enabled but required settings are missing.");
  }

  if (process.env.NEXTAUTH_SECRET.length < MIN_AUTH_SECRET_LENGTH) {
    throw new Error(
      `HOMEPAGE_AUTH_SECRET (or NEXTAUTH_SECRET) must be at least ${MIN_AUTH_SECRET_LENGTH} characters. Generate one with: openssl rand -base64 32`,
    );
  }
}

// Give fail2ban / CrowdSec etc something to match on
function logFailedPasswordSignIn() {
  createLogger("nextauth").warn("Failed password sign-in attempt");
}

let providers = [];
if (authEnabled) {
  if (hasOidcConfig) {
    providers = [
      {
        id: "homepage-oidc",
        name: process.env.HOMEPAGE_OIDC_NAME || "Homepage OIDC",
        type: "oauth",

View on GitHub (pinned to b6dca1ae03)

Solutions

  1. Generate a fresh secret: `openssl rand -base64 32` (produces ~44 chars).
  2. Set it as NEXTAUTH_SECRET and restart.
  3. If using a secret manager, ensure it emits at least 32 characters of high entropy.
  4. Rotate any existing sessions after changing the secret.

Example fix

// before
NEXTAUTH_SECRET=changeme

// after
NEXTAUTH_SECRET=$(openssl rand -base64 32)
Defensive patterns

Strategy: validation

Validate before calling

function assertSecretStrength(raw, min = 32) {
  if (typeof raw !== 'string' || raw.length < min) {
    throw new Error(`Secret must be at least ${min} chars. Generate: openssl rand -base64 32`);
  }
}
// preflight:
assertSecretStrength(process.env.NEXTAUTH_SECRET, 32);

Type guard

function isStrongSecret(v, min = 32) {
  return typeof v === 'string' && v.length >= min;
}

Prevention

When it happens

Trigger: authEnabled is true, NEXTAUTH_SECRET is set and passed the earlier presence checks, but `process.env.NEXTAUTH_SECRET.length < 32`. Common with placeholder values like 'secret', 'changeme', or a 16-char hex.

Common situations: Operator hardcoded a weak dev secret; reused a short API key; truncated output of a secret generator; copy-paste lost characters; older deploy with a now-non-compliant secret.

Related errors


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