TryGhost/Ghost · warning · Error
Failed to signout
Error message
Failed to signout
What it means
Thrown in api.member.signout() (apps/portal/src/utils/api.js:422) when DELETE /members/api/session/ returns non-ok. Message 'Failed to signout'. On success it does window.location.replace(siteUrl); on failure it throws without redirecting.
Source
Thrown at apps/portal/src/utils/api.js:422
},
signout(all = false) {
const url = endpointFor({type: 'members', resource: 'session'});
return makeRequest({
url,
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
all
})
}).then(function (res) {
if (res.ok) {
window.location.replace(siteUrl);
return 'Success';
} else {
throw new Error('Failed to signout');
}
});
},
async newsletters({uuid, key}) {
let url = endpointFor({type: 'members', resource: `member/newsletters`});
url = url + `?uuid=${uuid}&key=${key}`;
return makeRequest({
url,
credentials: 'same-origin'
}).then(function (res) {
if (!res.ok || res.status === 204) {
return null;
}
return res.json();
});
},
View on GitHub (pinned to 47d8b0e2ad)
Solutions
- Reload the page — if the session is already gone, Portal should treat the member as signed out anyway.
- Confirm third-party cookie blocking is not stripping the session cookie (especially in Safari/ITP).
- Check that the page origin matches siteUrl so the cookie scope covers the request.
- If the issue persists, clear site cookies and sign in again.
Example fix
// before
if (res.ok) { window.location.replace(siteUrl); return 'Success'; } else { throw new Error('Failed to signout'); }
// after: still redirect on session-already-gone (401)
if (res.ok || res.status === 401) { window.location.replace(siteUrl); return 'Success'; }
throw new Error(`Failed to signout (${res.status})`); Defensive patterns
Strategy: fallback
Validate before calling
// if the session cookie is missing, skip the call and just redirect
function hasSessionCookie() {
return document.cookie.split('; ').some(c => c.startsWith('ghost-members-session'));
} Try / catch
try {
await api.member.signout(all);
} catch (err) {
// err.message === 'Failed to signout'
// session is probably already gone — redirect anyway
window.location.replace(siteUrl);
} Prevention
- Treat 401/404 sign-out responses as success and still redirect.
- Ensure cookie scope covers the page origin so DELETE is authenticated.
- Disable edge caching for /members/api/session/.
- Avoid double sign-out across tabs.
When it happens
Trigger: Member clicks sign out; Portal DELETEs the session; the response is 4xx/5xx — typically the session cookie already expired, the CSRF token is missing, or the server cannot reach the session store.
Common situations: Session already invalid server-side; cookies blocked/cleared by the browser so the request lacks credentials; reverse proxy stripping cookies; cluster session store out of sync; user clicked sign-out in two tabs simultaneously.
Related errors
- Failed to update newsletter
- Failed to start a members session
- Failed to update member
- Failed to fetch site data
- fallbackMessage
AI-assisted analysis of TryGhost/Ghost@47d8b0e2ad (2026-08-13).
Data as JSON: /api/errors/d55536b475f7796e.
Report an issue: GitHub.