User required actions not sending the specific email when set through Admin UI or custom federation provider

Hey there,
I have implemented a custom user federation provider to migrate users from our “legacy” system to Keycloak. This works without any problems.

The problem or struggle occurs when I am setting the required actions to a specific user:

 getRequiredActions(legacyUserDetails)
                .forEach(keycloakUser::addRequiredAction);
 private Stream<UserModel.RequiredAction> getRequiredActions(LegacyUserDetails legacyUserDetails) {
        return requiredActionMap.entrySet()
                .stream()
                .filter(predicateSupplierEntry -> predicateSupplierEntry.getKey().test(legacyUserDetails))
                .map(it -> it.getValue().get());
    }

The required actions are set as expected to the specific user. They are also visible in the Keycloak admin console UI for the specific user, but Keycloak is not sending an E-Mail for example for the VERIFY_EMAIL required action.

I have also tried to remove and read the required action in the Keycloak admin console UI, but the result stays the same: No E-Mail is sent to the specific user. This is also the case for the UPDATE_PASSWORD action.

So, how to trigger the E-Mail sent for the required actions? If I migrate a user which E-Mail is not verified I need to sent a specific E-Mail.
The SMTP Server is configured, and Test Connection Mails are sent and received successfully.

The emails are not triggered by the addition of a required action. You need to call the execute-actions-email endpoint in the Admin API (Keycloak Admin REST API) for it to both add the required actions and send an email.

That makes not much sense to me.
I am inside a custom SPI within keycloak where I migrate the legacy users to keycloak and explicitly set the required actions.

If I understood you correctly, I need to use the Keycloak REST API inside the Keycloak context (as I am running a custom SPI) to invoke the Mail sending?

Yes, it is a bit confusing. That’s where the code is that will set a required action AND send the email to the user. I don’t know of a convenient place elsewhere it exists in the code that’s easy to call from an SPI. You can either:

  1. Load the provider from your SPI using the KeycloakSession getProvider(...) method to get and execute that method on the UserResource.
  2. Duplicate the code from the UserResource executeActionsEmail(...) method in your own SPI to set the required actions and send the email.
  3. Call that method in the Admin API from your SPI. If your SPI is an authenticated REST resource, you can use the token you got there. If not, you could use a service account to authenticate and call the API.

So what I have no tried, even if it is totally ugly:

 public class LegacyProvider implements UserStorageProvider,
         UserLookupProvider,
         CredentialInputUpdater,
       CredentialInputValidator {
....
 Keycloak instance = Keycloak.getInstance(
                "http://localhost:8080/auth/",
                "master",
                "admin", "myMasterPassword",
                "admin-cli");

....
instance.realm(realm.getName()).users().get(user.getId()).executeActionsEmail(user.getRequiredActionsStream().collect(Collectors.toList()));

But I am missing something. I always get


15:05:08,247 ERROR [org.keycloak.services.error.KeycloakErrorHandler] (default task-8) Uncaught server error: javax.ws.rs.ProcessingException: RESTEASY004655: Unable to invoke request: org.apache.http.conn.HttpHostConnectException: Connect to localhost:8080 [localhost/127.0.0.1] failed: Connection refused (Connection refused)