bytedance/deer-flow · error · HTTPException

Your email could not be verified by the identity provider. P

Error message

Your email could not be verified by the identity provider. Please contact your administrator.

What it means

HTTP 403 raised during SSO/OIDC user provisioning when the provider is configured with require_verified_email=true but the identity returned by the IdP has email_verified false or missing. DeerFlow refuses to provision or log in a user whose email the identity provider has not verified, because an unverified email cannot be trusted as an account identifier. Note the early return for an existing OAuth link means this only bites on first login or after the link table is cleared.

Source

Thrown at backend/app/gateway/auth/user_provisioning.py:45

) -> dict:
    """Resolve an OIDC identity to a DeerFlow user.

    Flow:
    1. Look up existing user by (provider, subject)
    2. If not found, enforce domain/email-verified rules
    3. Block if a local account already owns the email (never auto-link)
    4. Auto-create if enabled

    Returns a dict with ``user`` (the User model instance) and ``created`` (bool).
    """
    # 1. Existing OAuth link
    existing = await local_provider.get_user_by_oauth(provider_id, identity.subject)
    if existing:
        return {"user": existing, "created": False}

    # 2. Verified email requirement
    if provider_config.require_verified_email and not identity.email_verified:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail=("Your email could not be verified by the identity provider. Please contact your administrator."),
        )

    if not identity.email:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="The identity provider did not provide an email address.",
        )

    email = identity.email.lower()

    # 3. Domain restriction
    if provider_config.allowed_email_domains:
        domain = email.rsplit("@", 1)[-1]
        if domain not in {d.lower().lstrip("@") for d in provider_config.allowed_email_domains}:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,

View on GitHub (pinned to 1dd6ba1acb)

Solutions

  1. Verify the user's email at the identity provider, then retry the SSO login
  2. Fix the provider's claim mapping so email_verified is emitted in the ID token or userinfo
  3. If the provider genuinely cannot assert verification, set require_verified_email: false for that provider in config.yaml and restart the Gateway

Example fix

# config.yaml (provider entry)
# before
require_verified_email: true
# after
require_verified_email: false
Defensive patterns

Strategy: validation

Validate before calling

# In an OIDC callback wrapper, check the claim before calling provisioning
identity = await provider.exchange_code(code)
if provider_config.require_verified_email and not identity.email_verified:
    return RedirectResponse("/login?error=email_not_verified")

Try / catch

from fastapi import HTTPException
try:
    result = await provision_oauth_user(provider_id, identity, provider_config)
except HTTPException as e:
    if e.status_code == 403 and "verified" in e.detail:
        return redirect_to_login("email_not_verified")  # actionable user message
    raise

Prevention

When it happens

Trigger: First-time OIDC login where config.yaml's provider entry sets require_verified_email: true and the ID token / userinfo carries email_verified=false (or omits the claim). Any subsequent call to the provisioning function with no existing oauth link row for (provider_id, identity.subject).

Common situations: Keycloak/Dex/Auth0 test realms where users are created without email verification; enterprise IdPs that never emit email_verified; enabling require_verified_email after users were already using SSO; claim-name customization that drops the verified flag.

Related errors


AI-assisted analysis of bytedance/deer-flow@1dd6ba1acb (2026-08-14). Data as JSON: /api/errors/acd668f72451e908. Report an issue: GitHub.