TryGhost/Ghost · error · BadRequestError
Could not determine origin of request. Please ensure an…
Error message
Could not determine origin of request. Please ensure an Origin or Referrer header is present.
What it means
A BadRequestError from `assignUserToSession` when `origin` is falsy. Ghost derives the request origin from the `Origin` header first, then falls back to `Referer`; if neither is present it cannot bind a trusted origin to the session and refuses to proceed. This is the login/session-creation path, so a missing origin is treated as an untrustworthy request.
Solutions
- Send an `Origin` header matching the configured admin URL on the request.
- For automation/integrations, use the Admin API with a Staff token/key instead of the browser session flow.
- Disable the browser extension/config that strips `Origin`/`Referer` for the admin domain.
- Ensure any reverse proxy forwards the original `Origin`/`Referer` headers to Ghost.
Example fix
// before
curl -X POST https://example.com/ghost/api/admin/session/ -d '...'
// after
curl -X POST https://example.com/ghost/api/admin/session/ \
-H 'Origin: https://example.com' \
-H 'Content-Type: application/json' \
-d '{...}' Defensive patterns
Strategy: validation
Validate before calling
function ensureRequestOrigin(headers) {
const origin = headers.origin || (headers.referer ? new URL(headers.referer).origin : null);
if (!origin) throw new Error('Missing Origin/Referer header; cannot bind session origin');
return origin;
} Type guard
const hasOriginOrReferer = (h) => Boolean(h?.origin || h?.referer);
Try / catch
try {
await api.session.create(credentials);
} catch (err) {
if (err.type === 'BadRequestError' && /Origin or Referrer/i.test(err.message)) addOriginHeader();
else throw err;
} Prevention
- Always send an Origin header on session/auth requests.
- For automation, use the Admin API key flow, not the browser session flow.
- Disable header-stripping extensions for the admin domain.
When it happens
Trigger: A login or session-initiation request that carries neither an `Origin` nor a `Referer` header — e.g. a direct `fetch`/`curl` without those headers, a browser request that strips them, or a privacy/proxy setup that removes both.
Common situations: Calling the session/auth endpoints from a server-side script or `curl` with no `Origin`/`Referer`; a strict privacy browser or extension stripping these headers; a non-browser client (CLI/SDK) hitting the user-facing auth flow instead of the API-key flow; a redirect chain that drops the `Referer`.
Related errors
- Could not fetch user from the session.
- Request made from incorrect origin. Expected
- Request made from incorrect origin. Expected
- Download failed
- Email is not valid
AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13).
Data as JSON: /api/errors/09ec2068abfe065b.
Report an issue: GitHub.
Appendix: source
Thrown at ghost/core/core/server/services/auth/session/session-service.js:173
/**
* isVerificationRequired
* Determines if 2FA verification is required based on site settings
* @returns {boolean}
*/
function isVerificationRequired() {
return getSettingsCache('require_email_mfa') === true;
}
async function assignUserToSession({
session,
user,
origin,
userAgent,
ip,
verificationToken
}) {
if (!origin) {
throw new BadRequestError({
message: 'Could not determine origin of request. Please ensure an Origin or Referrer header is present.'
});
}
if (session.user_id && session.user_id !== user.id) {
invalidateAuthCodeChallenge(session);
}
session.user_id = user.id;
session.origin = origin;
session.user_agent = userAgent;
session.ip = ip;
// If a verification token was provided with the login request, verify it
if (verificationToken) {
const secret = getSettingsCache('admin_session_secret');
const isAuthCodeVerified = verifyAuthCode(session, verificationToken, secret);
View on GitHub (pinned to 47d8b0e2ad)