immich-app/immich · error · BadRequestException
Received backchannel logout request but OAuth is not enabled
Error message
Received backchannel logout request but OAuth is not enabled
What it means
backchannelLogout handles OIDC Back-Channel Logout requests from the identity provider. It first requires that OAuth is enabled in the server config; if oauth.enabled is false, the request is rejected with this BadRequestException (400) because there is no OAuth session machinery to process a logout for.
Solutions
- Remove the Backchannel Logout URL from the OAuth client configuration in your identity provider, or point it at the correct Immich instance.
- Re-enable OAuth (Administration > Settings > Authentication > OAuth) if the IdP logout notifications are expected.
- Ignore/skip 400s for this endpoint in the IdP logs if OAuth is intentionally disabled.
- Sync Immich's oauth.enabled setting with the IdP client registration lifecycle.
Example fix
// before: IdP sends logout to a server with oauth disabled -> 400 // after (Keycloak admin): remove the Backchannel Logout URL // Client > Advanced > Backchannel Logout URL: <empty> (OAuth disabled in Immich)
Defensive patterns
Strategy: try-catch
Validate before calling
// IdP-side: only register the backchannel logout URL when Immich has oauth.enabled=true const cfg = await api.getServerConfig(); console.assert(cfg.oauthEnabled, 'Immich OAuth disabled; do not register backchannel logout URL');
Try / catch
try { await idp.registerBackchannel(immichUrl); } catch (e) { logWarnOnce('Immich rejected backchannel logout; OAuth disabled'); } Prevention
- Remove backchannel logout URLs when disabling OAuth in Immich
- Keep OAuth enablement symmetric between IdP client config and Immich settings
- Filter expected 400s from IdP logs during intentional disablement
When it happens
Trigger: The IdP posts a backchannel-logout request (with logout_token) to /api/oauth/backchannel-logout while the Immich server config has oauth.enabled === false — i.e. OAuth was disabled after the IdP was configured to send logout notifications.
Common situations: Admin disabling OAuth in Immich but forgetting to remove the back-channel logout URL in Keycloak/Auth0/Okta; IdP sending logout broadcasts to all registered clients after OAuth was toggled off; misconfigured instance pointing at the wrong server.
Related errors
- Invalid logout token: no claims found
- Error backchannel logout: token validation failed
- Invalid logout token: it must contain either a sub or a sid…
- Password login has been disabled
- Error in OAuth discovery
AI-assisted analysis of immich-app/immich@f48d4b3321 (2026-09-15).
Data as JSON: /api/errors/693b95ca92d96781.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/auth.service.ts:97
async logout(auth: AuthDto, authType: AuthType): Promise<LogoutResponseDto> {
let oauthBearerToken: string | undefined;
if (auth.session) {
const session = await this.sessionRepository.get(auth.session.id);
oauthBearerToken = session?.oauthBearerToken ?? undefined;
await this.sessionRepository.delete(auth.session.id);
await this.eventRepository.emit('SessionDelete', { sessionId: auth.session.id });
}
return {
successful: true,
redirectUri: await this.getLogoutEndpoint(authType, oauthBearerToken),
};
}
async backchannelLogout(dto: OAuthBackchannelLogoutDto): Promise<void> {
const { oauth } = await this.getConfig({ withCache: false });
if (!oauth.enabled) {
throw new BadRequestException('Received backchannel logout request but OAuth is not enabled');
}
let claims;
try {
claims = await this.oauthRepository.validateLogoutToken(oauth, dto.logout_token);
} catch (error: Error | any) {
this.logger.error(`Error backchannel logout: ${error.message}`);
this.logger.error(error);
throw new BadRequestException('Error backchannel logout: token validation failed');
}
if (!claims) {
throw new BadRequestException('Invalid logout token: no claims found');
}
if (!claims.sub && !claims.sid) {
throw new BadRequestException('Invalid logout token: it must contain either a sub or a sid claim');View on GitHub (pinned to f48d4b3321)