{"record":{"id":"693b95ca92d96781","repo":"immich-app/immich","slug":"received-backchannel-logout-request-but-oauth-is-n","errorCode":null,"errorMessage":"Received backchannel logout request but OAuth is not enabled","messagePattern":"Received backchannel logout request but OAuth is not enabled","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/auth.service.ts","lineNumber":96,"sourceCode":"  async logout(auth: AuthDto, authType: AuthType): Promise<LogoutResponseDto> {\n    let oauthBearerToken: string | undefined;\n    if (auth.session) {\n      const session = await this.sessionRepository.get(auth.session.id);\n      oauthBearerToken = session?.oauthBearerToken ?? undefined;\n      await this.sessionRepository.delete(auth.session.id);\n      await this.eventRepository.emit('SessionDelete', { sessionId: auth.session.id });\n    }\n\n    return {\n      successful: true,\n      redirectUri: await this.getLogoutEndpoint(authType, oauthBearerToken),\n    };\n  }\n\n  async backchannelLogout(dto: OAuthBackchannelLogoutDto): Promise<void> {\n    const { oauth } = await this.getConfig({ withCache: false });\n    if (!oauth.enabled) {\n      throw new BadRequestException('Received backchannel logout request but OAuth is not enabled');\n    }\n\n    let claims;\n    try {\n      claims = await this.oauthRepository.validateLogoutToken(oauth, dto.logout_token);\n    } catch (error: Error | any) {\n      this.logger.error(`Error backchannel logout: ${error.message}`);\n      this.logger.error(error);\n\n      throw new BadRequestException('Error backchannel logout: token validation failed');\n    }\n\n    if (!claims) {\n      throw new BadRequestException('Invalid logout token: no claims found');\n    }\n\n    if (!claims.sub && !claims.sid) {\n      throw new BadRequestException('Invalid logout token: it must contain either a sub or a sid claim');","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/auth.service.ts#L78-L114","documentation":"Thrown by AuthService.backchannelLogout when a back-channel logout request arrives but the server's oauth.enabled config is false. The OpenID Connect back-channel logout endpoint is only valid when OAuth is configured, so any request to it while OAuth is disabled is rejected with 400 BadRequest.","triggerScenarios":"The Identity Provider (IdP) sends a back-channel logout to /oauth/backchannel-logout (or equivalent) but the server has oauth.enabled=false; admin disabled OAuth without updating the IdP's registered logout endpoint.","commonSituations":"OAuth was turned off in server config while the IdP still has the back-channel URL registered; misrouted logout callback hitting the wrong instance; staging/prod config drift where one environment has OAuth off.","solutions":["Re-enable OAuth in server system config if back-channel logout is expected.","Remove the back-channel logout URL from the IdP client configuration if OAuth is intentionally disabled.","Ensure the IdP points at an instance that actually has OAuth enabled."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Check OAuth is enabled before expecting back-channel logout to work.\nconst { data: oauth } = await api.get('/oauth/config');\nif (!oauth.enabled) {\n  throw new Error('OAuth disabled; back-channel logout will be rejected.');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep the IdP's back-channel logout URL and the server's oauth.enabled in sync.","When disabling OAuth, remove the back-channel URL from the IdP client.","Point the IdP at an instance that actually has OAuth enabled."],"tags":["auth","oauth","logout","backchannel","config"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}