Skip to content
Menu
DevSecOps Now!!!
  • About
  • Certifications
  • Contact
  • Courses
  • DevSecOps Consulting
  • DevSecOps Tools
  • Training
  • Tutorials
DevSecOps Now!!!

How to Skip the Activation Email and Password Reset After Google Login in Keycloak Auto-Link Existing Users in First Broker Login

Posted on May 13, 2026

Limited Time Offer!

For Less Than the Cost of a Starbucks Coffee, Access All DevOpsSchool Videos on YouTube Unlimitedly.
Master DevOps, SRE, DevSecOps Skills!

Enroll Now

The real issue was not Laravel. Laravel was only redirecting users to Keycloak. The mess was inside Keycloak’s first broker login flow, Google IdP settings, and old UPDATE_PASSWORD required actions left on migrated users. This article follows the exact fix brief you provided.

Table of Contents

  • The Real Problem: Keycloak Google Login Activation Email
  • Why This Happens in Keycloak
  • Step A: Duplicate the Built-in First Broker Login Flow
  • Step B: Configure the Duplicated Flow Requirements
  • Step C: Bind the New Flow to the Google Identity Provider
  • Step D: Disable UPDATE_PASSWORD Required Action Realm-Wide
  • Step E: Clean Pending UPDATE_PASSWORD for Migrated Users
  • Step F: Optional Laravel Code-Side Hardening
  • Common Gotchas
  • How to Verify the Fix
  • Conclusion
  • FAQ

The Real Problem: Keycloak Google Login Activation Email

The main symptom was simple: Keycloak Google login activation email behavior appeared even though Google had already verified the user’s email.

Our stack looked like this:

  • Laravel application
  • Self-hosted Keycloak
  • Google configured as an Identity Provider
  • Login redirected with idp_hint=google
  • Some users already existed in Keycloak because they were migrated earlier

The symptoms were annoying:

  1. Brand-new Google users received an email verification link.
  2. Existing users saw an “Account already exists” page.
  3. After linking, some users were pushed into a “set new password” screen.
  4. This happened even for users who should only ever log in through Google.

That last point matters.

If your product uses Google SSO as the primary login method, asking users to set a local Keycloak password makes no sense. It creates support tickets, confusion, and that classic “but I already logged in” complaint.

The goal was:

  • Trust Google’s verified email.
  • Auto-link Google users to existing Keycloak users by email.
  • Skip the “confirm link existing account” page.
  • Skip email verification.
  • Skip password reset for Google-only users.
  • Keep the flow clean for Laravel.

Why This Happens in Keycloak

Keycloak’s default first broker login flow is cautious by design. It is used when a user logs in through an external Identity Provider for the first time and Keycloak does not yet have that external identity linked to a local user. Keycloak’s docs describe the First Broker Login flow as the flow used during first login with an identity provider. (Keycloak)

That caution is useful in many enterprise environments.

But in a Google SSO flow, it can feel too cautious.

Here were the root causes:

Root Cause A: Default First Broker Login Flow Verifies Existing Accounts

When Keycloak detects an email match, the default flow can run “Verify existing account by Email.”

That means:

  • Google says the email is verified.
  • Keycloak still says, “Cool, but let me verify that again.”
  • User receives an activation or verification email.

This is where the Keycloak Google login activation email problem starts.

Root Cause B: Google Trust Email Was Off

The Google IdP setting Trust Email was disabled.

When Trust Email is off, Keycloak does not fully trust the email_verified claim from Google. So even though Google has already verified the email, Keycloak behaves like it still needs proof.

Root Cause C: Migrated Users Had UPDATE_PASSWORD Pending

Some users were migrated into Keycloak with this required action:

UPDATE_PASSWORD

So even after Google auto-linking worked, Keycloak still forced them to set a local password.

That created the keycloak update password loop feeling.

What’s actually going on under the hood

Google login and Keycloak local credentials are separate things. Linking a Google identity to a Keycloak user does not automatically clear old required actions. If UPDATE_PASSWORD is still pending, Keycloak will still ask for it.

Step A: Duplicate the Built-in First Broker Login Flow

Go to:

Authentication → Flows → first broker login

Open the action menu and duplicate it.

Use this name:

first broker login - auto link

Why duplicate?

Because Keycloak does not allow you to safely modify built-in flows in the way we need. If you try to add executions directly to a built-in flow, you can hit this error:

It is illegal to add execution to a built in flow

So don’t fight Keycloak here. Duplicate first.

Keycloak’s own guidance for changing first broker login behavior also starts by duplicating the flow before editing it, so this is the safe path. (Keycloak)

Image suggestion: screenshot of Authentication → Flows showing the duplicated first broker login - auto link flow.

Step B: Configure the Duplicated Flow Requirements

Now edit your duplicated flow.

The final target structure should look like this:

first broker login - auto link
├── Review Profile                          DISABLED
├── User creation or linking                REQUIRED
│   ├── Create User If Unique               ALTERNATIVE
│   └── Handle Existing Account             ALTERNATIVE
│       ├── Automatically set existing user REQUIRED
│       ├── Confirm link existing account   DISABLED
│       └── Account verification options    DISABLED
│           └── (children stay DISABLED)
└── Conditional Organization                CONDITIONAL

The important change is here:

Handle Existing Account
└── Automatically set existing user REQUIRED

This is the idp-auto-link behavior.

It tells Keycloak:

“An existing local user was found. Automatically set that existing user instead of asking the user to confirm the link by email.”

Disable Review Profile

Set:

Review Profile = DISABLED

This avoids showing the profile review page when Google already provides the expected email/profile data.

Keep User Creation or Linking Required

Set:

User creation or linking = REQUIRED

Inside it:

Create User If Unique = ALTERNATIVE
Handle Existing Account = ALTERNATIVE

This means:

  • If no user exists, create one.
  • If an email match exists, handle the existing account.

Add Automatically Set Existing User Inside Handle Existing Account

This is the critical part.

You must add:

Automatically set existing user = REQUIRED

inside:

Handle Existing Account

Not at the root.

Not beside User creation or linking.

Inside the existing account sub-flow.

Critical gotcha

Automatically set existing user must be inside Handle Existing Account. If you add it at the root level, Keycloak does not have the duplicated-user context available.

Here is the error you may see if you add it in the wrong place:

AuthenticationFlowException: Unexpected state. There is no existing duplicated user identified in ClientSession
    at IdpAutoLinkAuthenticator.authenticateImpl

In the browser, Keycloak may show a misleading message:

Invalid username or password

That error is not really about the Google password. It means the flow structure is wrong.

The duplicated user reference exists only inside the Handle Existing Account context. If idp-auto-link runs before that context exists, Keycloak has no existing user to attach.

Disable Confirm Link Existing Account

Set:

Confirm link existing account = DISABLED

This removes the “Account already exists” confirmation page.

This matters because Trust Email alone will not skip the account confirmation page. Trust Email tells Keycloak whether the external email can be trusted. It does not automatically remove the confirm-link step.

Disable Account Verification Options

Set:

Account verification options = DISABLED

Also keep its children disabled.

That removes the old email verification path from this Google-first login journey.

Gotcha

If a REQUIRED sub-flow has all children disabled, Keycloak can fail in confusing ways. Keep the parent and child requirements aligned exactly as shown above.

Step C: Bind the New Flow to the Google Identity Provider

Now go to:

Identity Providers → google → Settings

Set:

Trust Email = ON
First Login Flow override = first broker login - auto link
Sync Mode = Force

Then click Save.

Do not just toggle and leave the page. Some Keycloak versions are not forgiving if you forget to save.

Why Trust Email Must Be On

Google sends an email_verified claim.

When Trust Email is enabled, Keycloak trusts that claim and does not treat the email as unverified.

This is what helps remove the skip verify email keycloak issue for Google users.

Why First Login Flow Override Matters

You do not need to change the global first broker login flow for every Identity Provider.

Bind your custom flow only to Google:

First Login Flow override = first broker login - auto link

That keeps this behavior scoped.

Sync Mode: Force vs Import

Use:

Sync Mode = Force

when you want Keycloak to update user data from Google during login.

Use:

Sync Mode = Import

when you only want Keycloak to import user data once during first login and then keep local values afterward.

For most Google SSO setups where Google is the source of truth for profile basics, Force is usually the cleaner option.

Gotcha

Sync Mode does not fix account linking by itself. It controls how brokered user data is synced. You still need the first broker login flow changes.

Step D: Disable UPDATE_PASSWORD Required Action Realm-Wide

Now go to:

Authentication → Required Actions → Update Password

Set:

Enabled = Off
Default Action = unchecked

This prevents Keycloak from assigning UPDATE_PASSWORD as a default required action going forward.

This is especially important for Google-only realms.

If the user never needs a local Keycloak password, forcing password update is just noise.

Gotcha

Disabling a required action does not automatically remove that action from existing users. It only affects future behavior.

Step E: Clean Pending UPDATE_PASSWORD for Migrated Users

Before running SQL, back up the Keycloak database.

Seriously. Do not skip this.

Then run:

DELETE FROM user_required_action
WHERE required_action = 'UPDATE_PASSWORD'
  AND user_id IN (
    SELECT id FROM user_entity
    WHERE realm_id = (SELECT id FROM realm WHERE name = '<your-realm>')
  );

Replace:

<your-realm>

with your actual realm name.

For example:

DELETE FROM user_required_action
WHERE required_action = 'UPDATE_PASSWORD'
  AND user_id IN (
    SELECT id FROM user_entity
    WHERE realm_id = (SELECT id FROM realm WHERE name = 'mhn')
  );

This clears the pending password reset action from already-migrated users.

That is what stops the keycloak update password loop for existing Google users.

Production warning

Run a backup first. Then test this query in staging. Then run it in production during a safe maintenance window if your user base is active.

Step F: Optional Laravel Code-Side Hardening

If your Laravel app provisions Keycloak users through the Admin API, check your user creation logic.

You may have something like this:

// before
$requiredActions = $requirePasswordUpdate ? ['UPDATE_PASSWORD'] : [];

For a Google-only realm, change it to:

// after
$requiredActions = [];

That prevents new users from being created with UPDATE_PASSWORD attached.

A more defensive version:

$isGoogleOnlyRealm = true;

$requiredActions = [];

if (!$isGoogleOnlyRealm && $requirePasswordUpdate) {
    $requiredActions[] = 'UPDATE_PASSWORD';
}

If your app supports both password login and Google login, do not blindly remove password actions for every user. Apply this only where it makes sense.

Example:

$requiredActions = [];

if ($loginMode === 'password' && $requirePasswordUpdate) {
    $requiredActions[] = 'UPDATE_PASSWORD';
}

The rule is simple:

  • Google-only user? Do not require local password update.
  • Password-based user? Required password update may still be valid.

Common Gotchas

Gotcha 1: “It is illegal to add execution to a built in flow”

You edited the built-in flow directly.

Fix:

Duplicate first broker login first.
Edit the duplicated flow.
Bind the duplicated flow to Google.

Gotcha 2: “Invalid username or password” After Flow Edits

This is often not a password issue.

Common causes:

  • Automatically set existing user was added at the root level.
  • It was not added inside Handle Existing Account.
  • A REQUIRED sub-flow has all children disabled.
  • Flow requirements are inconsistent.

Fix the tree structure first.

Gotcha 3: Required Actions Do Not Retroactively Clear Existing Users

Turning off Update Password does not clean users who already have:

UPDATE_PASSWORD

in user_required_action.

That is why the SQL cleanup matters.

Gotcha 4: Trust Email Alone Is Not Enough

Trust Email helps Keycloak trust Google’s verified email claim.

But it does not automatically skip:

Confirm link existing account

You must disable that execution in the custom first broker login flow.

Gotcha 5: Force vs Import Sync Mode

Use Force if Google should keep updating profile data.

Use Import if Keycloak should import once and then local Keycloak data should win.

Neither one replaces proper auto-link flow configuration.

How to Verify the Fix

Always test in an incognito window.

Cached Keycloak sessions can make you think the fix worked when you are just reusing an old session.

Checklist

  • Open incognito/private browser.
  • Start Laravel login with Google.
  • Confirm no email verification link is sent.
  • Confirm no “Account already exists” screen appears.
  • Confirm no password reset screen appears.
  • Confirm user lands back in Laravel successfully.
  • In Keycloak Admin, open:
Users → <email> → Identity Provider Links

You should see:

google

linked to the user.

Check Keycloak Logs

Tail the logs while testing.

For systemd:

journalctl -u keycloak -f

Look for success:

SUCCESS: type="IDENTITY_PROVIDER_LOGIN"

Watch for failure:

FAILURE: type="IDENTITY_PROVIDER_FIRST_LOGIN_ERROR"

If you see first login errors, re-check the flow tree.

Most failures come from the Automatically set existing user execution being in the wrong place.

Conclusion

The fix was not in Laravel. Laravel was only starting the login journey. The real fix was in Keycloak’s Google Identity Provider settings, the duplicated first broker login flow, and old required actions left behind during migration.

Once we enabled Trust Email, added Automatically set existing user inside Handle Existing Account, disabled confirm-link verification, and cleaned UPDATE_PASSWORD, the login became normal again.

Google users logged in with Google. Existing users auto-linked. No activation email. No password reset loop. No weird “account already exists” wall.

If you are fighting the same Keycloak Google login activation email issue, start with the flow tree. That is usually where the ghost is hiding.

FAQ

1. Why does Keycloak send an activation email after Google login?

Because the default first broker login flow may still verify existing accounts by email. If Google Trust Email is off, Keycloak does not fully trust Google’s verified email claim.

2. How do I auto-link an existing user in Keycloak Google login?

Duplicate the first broker login flow, add Automatically set existing user inside Handle Existing Account, disable confirm-link verification, and bind the custom flow to the Google IdP.

3. Where should idp-auto-link be added in Keycloak?

It must be added inside:

User creation or linking → Handle Existing Account

Do not add it at the root level.

4. Why am I getting “There is no existing duplicated user identified in ClientSession”?

Because Automatically set existing user is running outside the context where Keycloak has identified the duplicate user. Move it inside Handle Existing Account.

5. Does Trust Email skip the Account Already Exists page?

No. Trust Email only tells Keycloak to trust the IdP’s verified email claim. To skip the account confirmation page, disable Confirm link existing account in the first broker login flow.

6. Why does Keycloak still ask Google users to update password?

Because the user already has UPDATE_PASSWORD in user_required_action. Disable the required action for the realm and clean existing pending actions from the database.

7. Should I use Sync Mode Force or Import for Google?

Use Force if Google should keep updating user profile data. Use Import if you only want to import profile data once and then manage it locally in Keycloak

Post Views: 8
  • Google Login
  • Google Login in Keycloak
  • How to Skip the Activation Email and Password Reset After Google Login in Keycloak Auto-Link Existing Users in First Broker Login
  • Keycloak
Subscribe
Login
Notify of
guest
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
  • How to Skip the Activation Email and Password Reset After Google Login in Keycloak Auto-Link Existing Users in First Broker Login
  • Free SSL Certificate Generation Tutorial for Any Website Using Certbot and Apache
  • The Ultimate Guide to Certified FinOps Professional: Skills, Levels, and Career Impact
  • Certified FinOps Manager: Essential Skills for Modern Cloud Operations
  • How to Use Claude AI for Programming: Complete Guide for Developers to Boost Productivity
  • The Definitive Guide to Certified FinOps Engineer: Master Cloud Value Engineering
  • A Comprehensive Guide to the Certified FinOps Architect Certification and Training
  • Linux Server Diagnostic Commands: Complete Guide for Performance, Network & System Troubleshooting
  • The Ultimate Guide to CDOM – Certified DataOps Manager Certification
  • The Practical Path to AI Reliability: A Guide to the Certified MLOps Manager
  • Master the Machine Learning Lifecycle:Guide to Becoming a Certified MLOps Architect
  • How to Build a Project-Level AI Memory System That Works Across Codex, Claude, and Other AI Coding Tools
  • Certified MLOps Professional: A Deep Dive into the Certified MLOps Professional Certification
  • Certified MLOps Engineer : The Comprehensive Guide to Mastering Machine Learning Operations
  • Codex vs Claude: A Complete Practical Guide for Modern Developers (2026)
  • Certified AIOps Professional Program A Guide to Career Growth
  • Keycloak Multi-Client Architecture with Project-Based Email Validation (Student, Trainer, Company, Consulting)
  • Incorrect definition of table mysql.column_stats
  • Mautic and PHP 8.3 Compatibility Guide (2026)
  • Certified AIOps Engineer: The Complete Career Path and Certification Guide
  • How to Rename Apache Virtual Host Files Safely (Step-by-Step Guide for Linux)
  • AIOps Foundation Certification: Everything You Need to Know to Get Certified
  • DevOps to Certified Site Reliability Professional: A Senior Mentor’s Guide
  • Certified Site Reliability Manager Training, Preparation, and Career Mapping
  • Certified Site Reliability Architect: The Complete Career Guide
  • What Is a VPN? A Complete Beginner-to-Advanced Tutorial
  • How to Install, Secure, and Tune MySQL 8.4 on Ubuntu 24.04 for Apache Event MPM and PHP-FPM
  • Complete Guide to Certified Site Reliability Engineer Career
  • Certified DevSecOps Professional Step by Step
  • Certified DevSecOps Manager: Complete Career Guide

Recent Comments

  1. emmy day on SQLSTATE[42S22]: Column not found: 1054 Unknown column ‘provider’ in ‘field list’
  2. digital banking on Complete Tutorial: Setting Up Laravel Telescope Correctly (Windows + XAMPP + Custom Domain)
  3. SAHIL DHINGRA on How to Uninstall Xampp from your machine when it is not visible in Control panel programs & Feature ?
  4. Abhishek on MySQL: List of Comprehensive List of approach to secure MySQL servers.
  5. Kristina on Best practices to followed in .httacess to avoid DDOS attack?

Archives

  • May 2026
  • April 2026
  • March 2026
  • February 2026
  • January 2026
  • December 2025
  • November 2025
  • October 2025
  • September 2025
  • August 2025
  • July 2025
  • June 2025
  • May 2025
  • April 2025
  • March 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • October 2024
  • September 2024
  • August 2024
  • July 2024
  • June 2024
  • May 2024
  • April 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • July 2023
  • May 2023
  • April 2023
  • March 2023
  • February 2023
  • January 2023
  • December 2022

Categories

  • Ai
  • AI Blogging
  • AiOps
  • ajax
  • Android Studio
  • Antimalware
  • Antivirus
  • Apache
  • Api
  • API Security
  • Api Testing
  • APK
  • Aws
  • Bike Rental Services
  • ChatGPT
  • Code Linting
  • Composer
  • cPanel
  • Cyber Threat Intelligence
  • Cybersecurity
  • Data Loss Prevention
  • Database
  • dataops
  • Deception Technology
  • DeepSeek
  • Devops
  • DevSecOps
  • DevTools
  • Digital Asset Management
  • Digital Certificates
  • Docker
  • Drupal
  • emulator
  • Encryption Tools
  • Endpoint Security Tools
  • Error
  • facebook
  • Firewalls
  • Flutter
  • git
  • GITHUB
  • Google Antigravity
  • Google play console
  • Google reCAPTCHA
  • Gradle
  • Guest posting
  • health and fitness
  • IDE
  • Identity and Access Management
  • Incident Response
  • Instagram
  • Intrusion Detection and Prevention Systems
  • jobs
  • Joomla
  • Keycloak
  • Laravel
  • Law News
  • Lawyer Discussion
  • Legal Advice
  • Linkedin
  • Linkedin Api
  • Linux
  • Livewire
  • Mautic
  • Medical Tourism
  • MlOps
  • MobaXterm
  • Mobile Device Management
  • Multi-Factor Authentication
  • MySql
  • Network Traffic Analysis tools
  • Paytm
  • Penetration Testing
  • php
  • PHPMyAdmin
  • Pinterest Api
  • Quora
  • SAST
  • SecOps
  • Secure File Transfer Protocol
  • Security Analytics Tools
  • Security Auditing Tools
  • Security Information and Event Management
  • Seo
  • Server Management Tools
  • Single Sign-On
  • Site Reliability Engineering
  • soft 404
  • software
  • SSL
  • SuiteCRM
  • SysOps
  • Threat Model
  • Twitter
  • Twitter Api
  • ubuntu
  • Uncategorized
  • Virtual Host
  • Virtual Private Networks
  • VPNs
  • Vulnerability Assessment Tools
  • Web Application Firewalls
  • Windows Processor
  • Wordpress
  • WSL (Windows Subsystem for Linux)
  • X.com
  • Xampp
  • Youtube
©2026 DevSecOps Now!!! | WordPress Theme: EcoCoded
wpDiscuz