gethomepage/homepage · critical · Error
HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) must be an absolute
Error message
HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) must be an absolute HTTP(S) URL without credentials, query, or fragment.
What it means
Thrown when the URL parses successfully but is rejected by strict shape rules: must be http/https, must not carry userinfo (user:pass@), query string, or fragment. Homepage enforces a clean origin-style URL because anything else breaks NextAuth callback/redirect logic and can leak credentials.
Source
Thrown at src/pages/api/auth/[...nextauth].js:54
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.",
);
}
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`,
);View on GitHub (pinned to b6dca1ae03)
Solutions
- Strip any query string and fragment — use only the origin (scheme + host + optional port).
- Remove any embedded user:pass@ credentials from the URL.
- Ensure the scheme is exactly http or https.
- If you need a non-standard port, include it on the host (https://home.example.com:8443) but nothing else.
Example fix
// before HOMEPAGE_EXTERNAL_URL=https://home.example.com/?next=/login#top // after HOMEPAGE_EXTERNAL_URL=https://home.example.com
Defensive patterns
Strategy: validation
Validate before calling
function assertOriginUrl(raw) {
const u = new URL(raw); // throws if invalid (see error 1)
if (!['http:', 'https:'].includes(u.protocol)) throw new Error('scheme must be http or https');
if (u.username || u.password) throw new Error('URL must not contain credentials');
if (u.search || u.hash) throw new Error('URL must not contain query or fragment');
return u;
} Type guard
function isCleanOriginUrl(v) {
if (!isValidAbsoluteUrl(v)) return false;
const u = new URL(v);
return ['http:', 'https:'].includes(u.protocol)
&& !u.username && !u.password && !u.search && !u.hash;
} Prevention
- Standardize on the origin only (scheme://host[:port]) in config.
- Reject deep links at the config layer so they never reach auth.
- Add a CI lint that checks HOMEPAGE_EXTERNAL_URL against ^https?://[^/?#]+$.
- Never embed basic-auth credentials in the URL.
When it happens
Trigger: NEXTAUTH_URL parses but parsedUrl.protocol is not 'http:'/'https:', OR parsedUrl.username/password/search/hash is non-empty. Examples: 'https://home.example.com/?x=1', 'https://u:p@home.example.com', 'https://home.example.com#section', 'ftp://home.example.com'.
Common situations: Operator appended a tracking query param or path fragment; reused a connection string that embeds basic-auth credentials; set an ws:// or ftp:// scheme by mistake; pasted a deep link instead of the site origin.
Related errors
- HOMEPAGE_EXTERNAL_URL (or NEXTAUTH_URL) must be an absolute
- Homepage auth is enabled but HOMEPAGE_EXTERNAL_URL (or NEXTA
- OIDC auth is enabled but required settings are missing.
- Password auth is enabled but required settings are missing.
- HOMEPAGE_AUTH_SECRET (or NEXTAUTH_SECRET) must be at least $
AI-assisted analysis of gethomepage/homepage@b6dca1ae03 (2026-08-13).
Data as JSON: /api/errors/89b80c2e92ec5cc0.
Report an issue: GitHub.