I suggest you start by finding out what exactly is returning a 401 error. SonarQube itself, or something sitting in front of the SonarQube Server (like a load balancer).
Concretely this means looking at your access.log to see if a 401 error is being reported upon hitting the /api/v2/system/email-configurations endpoint. Can you check that?
Based on nginx logs, I am getting error from the backend service: IP ADDRESS - - [17/Mar/2025:13:48:49 +0000] "POST /api/v2/system/email-configurations HTTP/2.0" 401 0 "https://sonarqube.my.host/admin/settings?category=email_notification" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36" 359 0.008 [sonarqube-sonarqube-9000] [] 10.42.0.68:9000 0 0.004 401 408dacdb2a241a76449f645a66250991
It is maybe worth mentioning that the GET method to the same endpoint succeeds /api/v2/system/email-configurations
But is the request actually making it to the SonarQube server? That’s what you’ll find out in the access.log file (which I assume is not what you’re showing me, since you mentioned nginx)
Have you tried configuring anything else on your server? I’d like to understand if it’s a problem with just SMTP settings, or if you also face the issue say, updating an exclusion or creating a new user (the former uses Web API v1, the latter Web API v2)
I’ve seen issues in the past where for some reason (bad cookies, bad loadblancer configuration) only POST requests are rejected, but they’re rejected across the board.
2025.03.17 13:58:21 TRACE web[7f543d4b-2d54-408a-96df-f5aac2e6be54][o.s.s.p.w.UserSessionFilter] Thread[http-nio-0.0.0.0-9000-exec-35,5,main] serves /api/v2/system/email-configurations
2025.03.17 13:58:21 TRACE web[7f543d4b-2d54-408a-96df-f5aac2e6be54][sql] time=0ms | sql=select st.uuid as uuid, st.user_uuid as "userUuid", st.expiration_date as "expirationDate", st.created_at as "createdAt", st.updated_at as "updatedAt" from session_tokens st where st.uuid=? | params=51a559ed-7eee-4234-b3a4-42de3503dd2d
2025.03.17 13:58:21 TRACE web[7f543d4b-2d54-408a-96df-f5aac2e6be54][sql] time=1ms | sql=SELECT sa.scm_account as "scm_account", u.uuid as uuid, u.login as login, u.name as name, u.email as email, u.active as "active", u.salt as "salt", u.crypted_password as "cryptedPassword", u.hash_method as "hashMethod", u.external_id as "externalId", u.external_login as "externalLogin", u.external_identity_provider as "externalIdentityProvider", u.user_local as "local", u.reset_password as "resetPassword", u.homepage_type as "homepageType", u.homepage_parameter as "homepageParameter", u.last_connection_date as "lastConnectionDate", u.last_sonarlint_connection as "lastSonarlintConnectionDate", u.created_at as "createdAt", u.updated_at as "updatedAt" FROM users u left outer join scm_accounts sa on sa.user_uuid = u.uuid WHERE u.uuid=? | params=9ae10a61-cef1-40bf-806f-b67c8ae03dde
2025.03.17 13:58:21 TRACE web[7f543d4b-2d54-408a-96df-f5aac2e6be54][sql] time=0ms | sql=select gr.role from group_roles gr inner join groups_users gu on gr.group_uuid=gu.group_uuid where gr.entity_uuid is null and gu.user_uuid=? union select gr.role from group_roles gr where gr.group_uuid is null and gr.entity_uuid is null union select ur.role from user_roles ur where ur.user_uuid=? and ur.entity_uuid is null | params=9ae10a61-cef1-40bf-806f-b67c8ae03dde, 9ae10a61-cef1-40bf-806f-b67c8ae03dde
2025.03.17 13:58:21 TRACE web[7f543d4b-2d54-408a-96df-f5aac2e6be54][sql] time=1ms | sql=select kee as "key", is_empty as empty, text_value as value, created_at as createdAt from internal_properties where kee in ( ? ) | params=email.smtp_host.secured