TryGhost/Ghost · error · BadRequestError
Request made from incorrect origin. Expected '${session.orig
Error message
Request made from incorrect origin. Expected '${session.origin}' received '${origin}'. What it means
A BadRequestError from the second CSRF check in `cookieCsrfProtection`. After the request origin passes the admin-URL check, the request origin must also match the origin stored on the session when it was created (`session.origin`). A mismatch indicates the request originates from a different host than the one that authenticated the session — a possible session-reuse or fixation attempt.
Source
Thrown at ghost/core/core/server/services/auth/session/session-service.js:149
// Check that the origin matches the admin URL to prevent cross-origin
// requests (e.g. no-cors form submissions from phishing sites)
const adminUrl = urlUtils.getAdminUrl() || urlUtils.getSiteUrl();
const adminOrigin = new URL(adminUrl).origin;
if (origin !== adminOrigin) {
throw new BadRequestError({
message: `Request made from incorrect origin. Expected '${adminOrigin}' received '${origin}'.`
});
}
// If there is no origin on the session object it means this is a *new*
// session, that hasn't been initialised yet. So we don't need CSRF protection
if (!session.origin) {
return;
}
if (session.origin !== origin) {
throw new BadRequestError({
message: `Request made from incorrect origin. Expected '${session.origin}' received '${origin}'.`
});
}
}
/**
* 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,View on GitHub (pinned to 47d8b0e2ad)
Solutions
- Have affected users log out and back in so the session stores the current admin origin.
- Fix the `url`/`admin.url` config so the request origin is stable and matches what is stored on new sessions.
- Ensure all nodes behind the load balancer derive the same `Origin` (consistent proxy headers).
- Avoid reusing session cookies across origins/tools; use the Admin API key flow for integrations instead.
Example fix
// before: changed admin url mid-session, requests now carry new origin
// session.origin still holds 'https://old.example.com'
// after: invalidate stale sessions after a domain/config change
await db.query('TRUNCATE TABLE sessions'); // or ask users to re-auth
// and pin config.url to the stable public origin Defensive patterns
Strategy: try-catch
Validate before calling
// Server-side config validation: ensure request origin equals session.origin before acting
function assertSessionOrigin(req) {
const origin = getOrigin(req);
if (req.session?.origin && req.session.origin !== origin) {
throw new Error('Session originated on a different host; re-authentication required');
}
} Type guard
const sessionMatchesOrigin = (session, origin) => !session?.origin || session.origin === origin;
Try / catch
try {
await api.admin.someAction();
} catch (err) {
if (err.type === 'BadRequestError' && /incorrect origin/i.test(err.message) && /received/.test(err.message)) relogin();
else throw err;
} Prevention
- After changing admin url config, clear/rotate sessions so users re-auth.
- Never reuse session cookies across origins or in CLI tools — use API keys.
- Ensure all load-balanced nodes derive the same request origin.
When it happens
Trigger: A request that passes the admin-URL origin check but whose `Origin`/`Referer`-derived origin differs from `session.origin`. This occurs when a session cookie is replayed from a different origin, when the admin URL changes after login (so new requests have a new origin but the session keeps the old one), or when the same cookie is used across two domains.
Common situations: The admin `url` config was changed after users logged in, invalidating their stored session origins; a load-balanced setup where `Origin` resolves differently per node; a user copied cookies to another tool/domain; mixed `http` vs `https` access changing the derived origin.
Related errors
- Request made from incorrect origin. Expected '${adminOrigin}
- Could not determine origin of request. Please ensure an Orig
- Could not fetch user from the session.
- Please verify your email settings
- Failed to update newsletter
AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13).
Data as JSON: /api/errors/714ed15a225aafc8.
Report an issue: GitHub.