immich-app/immich · error · BadRequestException

OAuth is not enabled

Error message

OAuth is not enabled

What it means

Thrown by authorize() when the OAuth configuration in server settings has enabled=false, fetched fresh with withCache:false. The OAuth login flow cannot start while the feature is disabled server-side.

Solutions

  1. Enable OAuth in admin settings (Administration > Settings > OAuth Authentication) with valid issuer/client ID/secret
  2. Hide the OAuth login option in clients when OAuth is intentionally off
  3. Clear stale cached config after changing settings
  4. Verify you are targeting the correct server URL

Example fix

// before
const cfg = await getConfig(); if (cfg.oauth) startOAuth();
// after
const cfg = await getConfig(); if (cfg.oauth?.enabled) startOAuth(); else usePasswordLogin();
Defensive patterns

Strategy: fallback

Validate before calling

const { oauth } = await api.getConfig(); if (!oauth || !oauth.enabled) usePasswordLogin();

Type guard

const oauthReady = (c: { oauth?: { enabled?: boolean } }) => c.oauth?.enabled === true;

Try / catch

try { await api.startOAuth(dto) } catch (e) { if (e.status === 400 && /OAuth is not enabled/.test(e.message)) return passwordLogin(); throw e; }

Prevention

When it happens

Trigger: Starting an OAuth login while the admin setting OAuth Authentication is disabled (oauth.enabled false).

Common situations: Fresh install where OAuth was never enabled; admin toggled OAuth off; clients still show an OAuth button; pointing at the wrong server instance.

Related errors


AI-assisted analysis of immich-app/immich@f48d4b3321 (2026-09-15). Data as JSON: /api/errors/837a032591a3970c. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/auth.service.ts:278

      return this.validateSession(session, headers);
    }

    if (apiKey) {
      return this.validateApiKey(apiKey);
    }

    throw new UnauthorizedException('Authentication required');
  }

  getMobileRedirect(url: string) {
    return `${MOBILE_REDIRECT}?${url.split('?', 2)[1] || ''}`;
  }

  async authorize(dto: OAuthConfigDto) {
    const { oauth } = await this.getConfig({ withCache: false });

    if (!oauth.enabled) {
      throw new BadRequestException('OAuth is not enabled');
    }

    return await this.oauthRepository.authorize(
      oauth,
      this.resolveRedirectUri(oauth, dto.redirectUri),
      dto.state,
      dto.codeChallenge,
    );
  }

  async callback(dto: OAuthCallbackDto, headers: IncomingHttpHeaders, loginDetails: LoginDetails) {
    const { oauth } = await this.getConfig({ withCache: false });
    if (!oauth.enabled) {
      throw new BadRequestException('OAuth is not enabled');
    }

    const expectedState = dto.state ?? this.getCookieOauthState(headers);
    if (!expectedState?.length) {

View on GitHub (pinned to f48d4b3321)