gethomepage/homepage · critical · Error
OIDC auth is enabled but required settings are missing.
Error message
OIDC auth is enabled but required settings are missing.
What it means
Thrown when full OIDC config is detected (issuer + clientId + clientSecret all present) but NEXTAUTH_SECRET is unset. NextAuth requires a secret to sign and/or encrypt its session JWTs; Homepage treats its absence as a hard blocker for the OIDC path.
Source
Thrown at src/pages/api/auth/[...nextauth].js:61
} 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.",
);
}
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");
}View on GitHub (pinned to b6dca1ae03)
Solutions
- Generate a secret: `openssl rand -base64 32`.
- Set it as NEXTAUTH_SECRET (Homepage also accepts HOMEPAGE_AUTH_SECRET in other places, but for this guard NEXTAUTH_SECRET must be populated).
- Restart the app so the module re-reads env.
- Verify the secret is at least 32 chars to also satisfy the downstream length check.
Example fix
// before HOMEPAGE_OIDC_ISSUER=https://idp.example.com HOMEPAGE_OIDC_CLIENT_ID=homepage HOMEPAGE_OIDC_CLIENT_SECRET=*** # no NEXTAUTH_SECRET // after NEXTAUTH_SECRET=$(openssl rand -base64 32)
Defensive patterns
Strategy: validation
Validate before calling
function validateOidc(env) {
const hasFull = env.HOMEPAGE_OIDC_ISSUER && env.HOMEPAGE_OIDC_CLIENT_ID && env.HOMEPAGE_OIDC_CLIENT_SECRET;
if (hasFull && !env.NEXTAUTH_SECRET) {
throw new Error('OIDC configured but NEXTAUTH_SECRET is missing');
}
} Type guard
function hasCompleteOidc(env) {
return Boolean(env.HOMEPAGE_OIDC_ISSUER && env.HOMEPAGE_OIDC_CLIENT_ID && env.HOMEPAGE_OIDC_CLIENT_SECRET);
} Prevention
- Generate NEXTAUTH_SECRET with `openssl rand -base64 32` on every deploy that uses auth.
- Use Docker/Kubernetes secrets rather than baking it into the image.
- Treat the OIDC triple as inseparable from the secret in env templates.
- Add a preflight check pairing OIDC + secret.
When it happens
Trigger: `hasOidcConfig` is true (HOMEPAGE_OIDC_ISSUER, HOMEPAGE_OIDC_CLIENT_ID, HOMEPAGE_OIDC_CLIENT_SECRET all set) and `process.env.NEXTAUTH_SECRET` is falsy. Path: `if (hasOidcConfig) { if (!process.env.NEXTAUTH_SECRET) throw ... }`.
Common situations: Operator moved from password auth to OIDC and forgot to add the secret; secret was loaded from a file/docker secret that wasn't mounted; misnamed the variable (HOMEPAGE_AUTH_SECRET is not read for this — only NEXTAUTH_SECRET is checked here).
Related errors
- Password auth is enabled but required settings are missing.
- Homepage auth is enabled but HOMEPAGE_EXTERNAL_URL (or NEXTA
- HOMEPAGE_AUTH_SECRET (or NEXTAUTH_SECRET) must be at least $
- HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) must be an absolute
- HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) must be an absolute
AI-assisted analysis of gethomepage/homepage@b6dca1ae03 (2026-08-13).
Data as JSON: /api/errors/dec58d893979c2b2.
Report an issue: GitHub.