SonarQube LDAP plugin creates a new user instead updating the existing user's email address

SonarQube Server / Developer Edition 9.9.4.87374 installed from zip on a Linux host.

We’ve been using LDAP authentication and authorization for years. Recently, our users received a mass update of email addresses on the LDAP server side (which are Active Directory servers BTW).

What I would expect in this case is SonarQube launching an LDAP query for the user on logon and updating the locally stored email address.

What happens instead:

  • A new user is created alongside the existing one, with an account name john_doe1234 and the new email address.
  • The login also fails with the following debug message in web.log:
2025.03.25 12:06:19 DEBUG web[AZXM+U7CLPeitRzfAAAL][auth.event] login failure [cause|Email 'john.doe@newaddress.com' is already used][method|FORM][provider|REALM|ldap][IP|127.0.0.1|10.164.192.100][login|john_doe]

Since the affected users are controlled by an external identity provider, I cannot fix their email addresses via the user administration GUI (/admin/users URL path). Email field is disabled and a “You cannot update the name and email of this user, as it is controlled by an external identity provider.” message is displayed.

Is this a genuine bug or did I miss something important here?
How do I make SonarQube refresh the email addresses of my users? What am I supposed to do with the duplicate john_doe1234 users?

1 Like

Hi,

Your version is past EOL. You should upgrade to either the latest version or the current LTA (long-term active version) at your earliest convenience. Your upgrade path is:

9.9.* → 2025.1.1-> 2025.2 (last step optional)

You may find these resources helpful:

If you have questions about upgrading, feel free to open a new thread for that here.

Regarding your question, we simply never accounted for the possibility of a mass email change. We generally say to keep your hands out of the database, but direct manipulation may be your only option.

 
Ann

We plan to upgrade in the future, but I wanted to solve the LDAP authentication problem before that upgrade happens.

we simply never accounted for the possibility of a mass email change

That is surprising, since I have contradictory (albeit unofficial and somewhat stale) information on that: Is there a way to disable the sonarqube ldap plugin email synchronization? - Stack Overflow

Also, a change in the data fetched from an external authentication provider seems like a very basic use case to me. I would not consider an email address change an arcane act that happens once in a decade and just for a few select users among millions…

We generally say to keep your hands out of the database, but direct manipulation may be your only option.

Can you be a bit more specific? Which table(s) and field(s) are we talking?

Hi,

You’re right; that’s stale. Things have changed a bit since then. IIRC, there was a recurring problem with conflicting email addresses, so we started adding the random number to the login to get past it.

Sorry, no.

 
Ann

IMHO this is a design failure. You had a handful of other, more sane options to solve this, such as:

  • Allow setting the same email address for multiple users. Why on Earth should emails be unique in a users table?
    (I did encounter the conflicting email addresses case a few years ago, too. I had two users to the same SQ instance in parallel: one with admin privileges and one with regular privileges for simulation purposes. Both synchronized from an LDAP source, both having the same email address. I was wondering back then: what good comes from forcing unique email addresses on users?)
  • Introduce a property for enabling/disabling user data updates from external sources.
  • No more email refresh from external sources? OK, but then allow modifying name and email from the GUI. The warning message SonarQube shows now (“You cannot update the name and email of this user, as it is controlled by an external identity provider.”) is a straight-faced lie. The external identity provider does not control the name and email of users anymore.

As for direct database manipulation: I did that and it does not seem to work.
I removed the duplicate john_doe1234 user created by SonarQube. I updated the original john_doe’s email address to john.doe@newdomain.com. I restarted both my DB and SonarQube to force clearing any potential cached user data. The login still fails and the following web.log entry is created:

2025.04.02 16:31:47 DEBUG web[AZX2u5FtAOd7aASaAACQ][auth.event] login failure [cause|Email 'john.doe@newdomain.com' is already used][method|FORM][provider|REALM|ldap][IP|127.0.0.1|10.164.1.2][login|john_doe]

To be clear: there is only one record in the USERS table with an john.doe@newdomain.com EMAIL field value. Both a DB SELECT and the GUI confirms this.

Is there perhaps a cache for user data that is not cleared by a service restart?

Hi,

There’s no cache.

If you were on a current version we might be able to help you more.

 
Ann

OK. Let’s pretend, I’m on a current version.

(After all, there might be others reading this topic, who encounter the same problem and are on the current version.)

OK, now we’re using the latest LTA (v2025.1.1 (104738) to be exact).

Some quick checks assured that the problem described above still persists.

Moreover:

  • I have removed the john_doe1234 user via database changes. This is the user that SQ created earlier with the john.doe@newaddress.com email address.
  • I updated (via DB UPDATE) the email field in the original john_doe users record to john.doe@newaddress.com

The login still fails:

2025.04.11 08:28:30 DEBUG web[649d7796-74e8-4f41-ab1d-e1d96c82dd4b][auth.event] login failure [cause|Email ‘john.doe@newaddress.com’ is already used][method|FORM][provider|REALM|ldap][IP|127.0.0.1|10.164.153.250][login|john_doe]

Which is funny, since the following two SELECT statements yield the same row:

SELECT * FROM users WHERE email = 'john.doe@newaddress.com';
SELECT * FROM users WHERE name = 'john_doe';

Hi,

Can you please share your full web.log, redacted as necessary?

 
Thx,
Ann

The full web.log currently weighs 562 MB (and counting).

Why:

  • When I started debugging this problem, I set the sonar.log.level.web property to DEBUG, so that I can see debug messages such as the one in my first and last comment.
  • The version upgrade happened today and these logs contain a lot of entries related to the upgrade process itself.

Previously (before the upgrade) SQ produced ~170-190 MBs of web.log per day. This is still too much volume to redact or share IMHO.

I can capture and share parts of the log that may refect details of specific events, such as a service startup or a login attempt.

Hi,

We don’t recommend running long-term with DEBUG-level logs. As you’ve seen, those get big, fast. What I was hoping for was

  • an INFO-level log from startup, showing the particulars of your instance, including plugins
  • then from the UI, switch briefly to DEBUG
  • attempt login
  • switch back to INFO logging in the UI
  • pull the log & ship it off to me

 
Thx,
Ann

1 Like

web.log (78.7 KB)

We have 5 LDAP servers, all 5 of them are successfully tested on startup. Later on, LDAPS queries throw several “No subject alternative DNS name matching addomain.local found.” exceptions, because 4 out of 5 LDAP servers have incorrect TLS certificate SANs. I consider this to be noise and not related to the root cause. Eventually, SonarQube finds and succesfully queries the single LDAP server that has a correct TLS certificate (mmm.addomain.local), see the last 4 log entries.

Hi,

I think this is about your 5 LDAP servers.

Per the docs:

SonarQube Server’s LDAP support is not designed to connect multiple servers in a failover mode.

When UserA is first authenticated with LDAP1, UserA is tied to LDAP1. UserA at LDAP2 is a different user with the same - conflicting - email address.

 
HTH,
Ann

1 Like

Argh. OK, now I get it, thanks for the clarification.

I still think that:

  • Enforcing unique emails in the users table is bad design.
  • Not refreshing email addresses from an external provider and also restricting the user from modifing the same email addresses from the GUI is bad design.
  • On startup, SQ does check all the LDAP servers configured, and successfully validates all of them. Minutes later, the actual LDAP queries fail with "No subject alternative DNS name matching addomain.local found.”. It looks like the actual LDAP queries do a different sort of SSL handshake than the tests than run on startup - this did not help in my case, neither.

But at least now I know how and why it fails, so at least I can work around this bad design.

1 Like

OK, let’s see how I finally managed to fix things.

Fair warning to the reader: my case may differ from your case significantly. Do NOT blindly apply the below steps without understanding what is done and why. Always start with a backup you can easily roll back to if anything goes south.

  1. Stopped the sonarqube service.

  2. First I had to fix the multi-server LDAP setup. (As it turned out, this sort of setup is not meant to work as a failover cluster, see above.) I practically reverted back to a single LDAP server setup.

2.1 First off, I edited the sonar.properties file. I started with multiple entries for most ldap properties such as:

ldap.server1.url=ldaps://server-one.foo.bar:636
ldap.server2.url=ldaps://server-two.foo.bar:636

I had to leave only one property for every such group of properties and I had to remove the middle part of the property key labeling the server. As in:

ldap.url=ldaps://server-one.foo.bar:636

2.2 I had to fix the external_identity field values of the users table. It looks like when you use a multi-server LDAP configuration, these fields designate the LDAP server used for the user’s first logon, as in: ‘LDAP_server1’ or ‘LDAP_server2’. I also noticed that if you use a single-server LDAP setup, then the external_identity_field is always ‘sonarqube’. (Local and external users can be told apart based on the user_local boolean field.)

UPDATE users SET external_identity_provider = 'sonarqube' WHERE external_identity_provider LIKE 'LDAP_%';

  1. The second problem I had to fix was the email addresses, which are only modifiable via SQL UPDATE statements.

3.1 I removed the jon_doe1234 user duplicates SQ created earlier. Since we do not have a lot of users, I handpicked them, one user at a time.

3.2 Then I updated the old email domain to the new email domain:

UPDATE users SET email = split_part(email, '@', 1) || '@newdomain.hu' WHERE email LIKE '%@olddomain.hu';

You may want to write a more specific WHERE clause to update a smaller subset of users.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.