Chrome headless automation keeps prompting for OTP verification on each session

I’m working on automated testing for a web application using Selenium with Java and Chrome in headless mode. The application I’m testing requires OTP authentication when logging in from a new device or browser for the first time. After the OTP is verified once, regular browsers remember this and don’t ask for OTP again on subsequent logins from the same machine.

However, when I run my automation script with Chrome headless, it keeps asking for OTP verification every single time, even though I’m running it from the same computer. I expected that after verifying the OTP once, it would remember this like a normal browser does.

Here’s my current setup:

System.setProperty("webdriver.chrome.driver", driverPath);
ChromeOptions options = new ChromeOptions();
options.setHeadless(true);
options.addArguments("--enable-javascript");
options.addArguments("--disable-gpu");
WebDriver browser = new ChromeDriver(options);
browser.manage().window().maximize();
browser.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
browser.get(applicationURL);

I tried entering the OTP manually through console input for the first run, thinking it would save the verification status, but Chrome headless still requests OTP on every execution. This makes automation difficult since I can’t manually enter OTP each time.

Interestingly, PhantomJS handled this correctly - after the first OTP verification, it wouldn’t ask again. But I need to stick with Chrome headless due to project requirements.

What Chrome capabilities or arguments should I add to make it behave like a regular browser and remember the OTP verification status?

yeah, headless chrome can be a pain lol. try adding --user-data-dir=/path/to/profile to keep the cookies like regular browsin. should help with those otp prompts. good luck!

Yeah, headless Chrome doesn’t save session data between runs by default. The user-data-dir fix works, but you need to check the profile directory permissions too. I’d add --disable-web-security and --disable-features=VizDisplayCompositor flags as well. I always create a dedicated profile directory and point Chrome there - fixes the OTP persistence every time. Just make sure your user-data-dir path exists and Chrome can write to it. Throwing in --no-first-run and --no-default-browser-check also helps keep sessions stable during automation.

This is super common with headless Chrome. Chrome treats each headless session like a brand new browser, so it doesn’t keep cookies, local storage, or device fingerprinting data that websites use to remember your device. Beyond the user-data-dir fix others mentioned, try adding --disable-blink-features=AutomationControlled - it stops some OTP triggers that specifically target automated browsers. Also throw in --disable-dev-shm-usage if you’re running this in a container, since memory issues can mess with session data. What worked for me was keeping a dedicated Chrome profile directory just for automation. Clean up between test runs but keep the authentication cookies. You might also try --remote-debugging-port=9222 - I’ve noticed it helps with session consistency.