Skip to content

Bug: login_url() breaks WPML / multi-domain setups — causes session loops and "Invalid verification code" #885

@masteradhoc

Description

@masteradhoc

Describe the bug

Reported in: https://wordpress.org/support/topic/two-factor-0-14-2-works-0-15-0-doesnt/
Affects: 0.15.0, 0.16.0
Last working version: 0.14.2

Description

On sites using WPML with multiple domain names (e.g. site.com, en.site.com,
fr.site.com), the plugin fails after 0.15.0 in two ways:

  • "ERROR: Invalid verification code." on TOTP login despite correct codes
  • Constant re-authentication prompts — every click in wp-admin logs the user out

Both symptoms disappear on downgrade to 0.14.2. The issue also affects multisite
setups where subsites run on separate domains.

Root cause

login_url() builds URLs using site_url( 'wp-login.php' ) directly, bypassing
WordPress's own wp_login_url(). WPML hooks the login_url filter to rewrite login
URLs per language/domain — but since two-factor never calls wp_login_url(), WPML
never fires. This causes the 2FA form action and redirect URLs to point to the wrong
domain, breaking nonce validation and session continuity.

Expected behaviour

login_url() should delegate to wp_login_url() so that the login_url filter
is respected, giving WPML (and Polylang, TranslatePress, etc.) the opportunity to
rewrite URLs correctly per language/domain.

Related

Steps to Reproduce

  1. Install WPML with two or more languages configured on separate domains/subdomains
  2. Enable Two Factor (TOTP) for a user
  3. Upgrade to 0.15.0+
  4. Log in — enter correct TOTP code
  5. Either: "Invalid verification code" error, or successful login followed by
    immediate logout on next click

Screenshots, screen recording, code snippet

No response

Environment information

  • WordPress 6.9.1
  • PHP 8.3
  • WPML with multi-domain setup
  • Two Factor 0.16.0

Please confirm that you have searched existing issues in this repository.

Yes

Please confirm that you have tested with all plugins deactivated except Two-Factor.

Yes

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

Status

In progress

Relationships

None yet

Development

No branches or pull requests

Issue actions