OIDC (Microsoft Entra ID) login always redirects to /user/link_account instead of auto-registering users

Description

I am configuring OpenID Connect authentication with Microsoft Entra ID (Azure AD) in Gitea. Authentication succeeds, but users are never auto-created. Instead, Gitea consistently redirects to:

/user/link_account

This occurs even when auto-registration is enabled and required claims appear to be configured.


Environment

  • Gitea version: latest (Docker image gitea/gitea:latest)

  • Deployment: Docker Compose

  • Database: PostgreSQL

  • Auth provider: Microsoft Entra ID (OIDC)


Configuration

Gitea app.ini (relevant sections)

[service]
DISABLE_REGISTRATION = true
ALLOW_ONLY_EXTERNAL_REGISTRATION = true
REQUIRE_SIGNIN_VIEW = true

[oauth2]
ENABLE_AUTO_REGISTRATION = true


OIDC Provider (Gitea UI)

  • Provider: OpenID Connect

  • Auto Discover URL: configured (Microsoft well-known endpoint)

  • Scopes: openid profile email

  • Auto Registration: enabled


Microsoft Entra Configuration

  • ID token optional claims added:

    • email

    • preferred_username

    • upn

  • API permissions:

    • openid

    • profile

    • email

  • Admin consent granted


Observed Behavior

  • OAuth flow completes successfully

  • Callback endpoint is hit:

    /user/oauth2/Microsoft/callback
    
    
  • Gitea returns HTTP 303 and redirects to:

    /user/link_account
    
    
  • No user is created automatically

Relevant logs:

GET /user/oauth2/Microsoft/callback ... 303 See Other
GET /user/link_account ... 200 OK


Expected Behavior

With ENABLE_AUTO_REGISTRATION = true, Gitea should:

  1. Extract user identity from OIDC claims

  2. Automatically create a new user

  3. Log the user in


Additional Notes / Debugging

  • Debug logging enabled ([log] LEVEL = debug)

  • No OIDC claims are printed in logs

  • Behavior is consistent across multiple login attempts

  • Manual user creation + account linking works


Suspected Issue

It appears Gitea is rejecting the OIDC identity for auto-registration, possibly due to:

  • Missing or untrusted email claim

  • Lack of email_verified

  • Incompatible or missing username mapping (preferred_username vs sub)

  • Strict validation of OIDC claims from Microsoft Entra

However, there is no clear log output indicating which field is failing validation.


Questions

  1. What exact claims are required for auto-registration to succeed?

  2. Does Gitea require email_verified = true?

  3. Which claim is used as the canonical username (sub, preferred_username, or email)?

  4. Is Microsoft Entra ID officially supported/tested with OIDC in Gitea?

  5. Can more verbose logging be enabled for OIDC claim validation failures?


Reproduction

  1. Configure Microsoft Entra OIDC provider

  2. Enable auto-registration in Gitea

  3. Attempt login via OAuth2

  4. Observe redirect to /user/link_account instead of account creation


Workaround

  • Manually creating users and linking accounts works

  • Considering using an intermediary IdP (e.g., Authentik) to normalize claims


Summary

OIDC authentication with Microsoft Entra succeeds, but auto-registration consistently fails without clear error messaging, forcing manual account linking.

Better documentation or logging around required claims and validation failures would help significantly.

I’m running into the exact same issues. Have you found a better workaround or a solution?

The best thing I found is to use a middleman like Authentik. I just use that for authentication for all my apps now because its a lot easier than setting up Entra for each app.

I have been fighting a similar issue th other day in another software stack (which led me to the Gitea forum). Eventually I adjusted the claims mapping in Entra: OIDC account email is not verified - using Entra · Issue #159 · ZimengXiong/ExcaliDash · GitHub

This is not saying that it will solve the logon issue in Gitea, but it might be worth a try :slight_smile:

1 Like

I know you found a solution, but wanted to let you know that I updated my oauth2 configuration to the following:

[oauth2_client]
ENABLE_AUTO_REGISTRATION = true
USERNAME = preferred_username
ACCOUNT_LINKING = auto
OPENID_CONNECT_SCOPES = openid profile email
UPDATE_AVATAR = true

And it is fixed now. I think the biggest unlock is the USERNAME = preferred_username line.

1 Like