Print this page

Best Practices For Handling Failed Logins

Knowledge Article Number 000212767
Description Failed logins to Salesforce can happen for a variety of reasons. An excessive number of failed logins can impact organization performance, user experience, and in the worst case, result in temporary IP blocks. This article describes some best practices when dealing with scenarios that result in excessive numbers of failed logins.
Resolution

Any access to a Salesforce organization requires a user login. This includes everything from normal Salesforce application access in a browser, to accessing your org via Salesforce1, to accessing your org programmatically via API calls. Logins can fail for a variety of reasons, including invalid login credentials, or org-level issues like incorrect user or org permissions. A single failed login doesn’t incur much overhead, however many repeated, simultaneous failed logins can result in a poor user experience.

In worst-case scenarios, if it’s determined failed logins are affecting general system performance, the IP making the failed login requests could be temporarily blocked to alleviate the issue. Note that this temporary block will also block valid logins coming from the same IP, so you want to fix excessive failed login problems before they get to this point.

This article talks about things you can do to make sure your logins are working as designed, and that you aren’t incurring a large number of failed logins.
 

Manage Password Expiration Settings

One of the most common causes of unexpected login failures is password expiration. If you attempt to log in with an expired password you’ll get an INVALID_OPERATION_WITH_EXPIRED_PASSWORD (“The users password has expired, you must call SetPassword before attempting any other API operations”) error.

You should write your integration code to gracefully handle this type of login failure (see “Check and Handle Login Errors” below), but there are ways to set up your organization to prevent expired passwords for specific user profiles. Enabling the “Password Never Expires” setting in the Administrative Permissions section of a profile will prevent passwords from expiring for all users using that profile. You can access profile settings via Setup, Manage Users, Profiles.

A common strategy is to create a new profile for your integration users, cloned from a standard profile if necessary, and enable the “Password Never Expires” setting. Using this approach makes it easy to avoid any login failures due to expired passwords.

See About Passwords and Profiles Overview for more information on passwords and profiles.

 

Check and Handle Login Errors

There are many causes of unsuccessful logins. Instead of writing code or adding processes to handle the different reasons behind an unsuccessful login, a simple solution is to try to login again, and continue to try this until either the login succeeds or a threshold of failed logins is met.

While this simplifies error handling, this approach creates unnecessary overhead with extra logins, and potentially fails to communicate the real problem to the user. If the system tries to login 10 times and gives up, instead of reporting that the user’s password has expired and directing the user to the appropriate page, you’ve added a performance hit to your org and simultaneously created a poor user experience.

Instead, work on adding appropriate login error handling to your application or process. Salesforce provides detailed responses to unsuccessful logins, and you can use the response info to determine what exactly is going wrong. Depending on which interface you’re using to log in to Salesforce, you’ll need to check for the error in the response, or similarly catch an exception that contains the error. Here’s an abridged example of handling login errors from the SOAP API login() call:

try { 
   // Using binding already set up, log in
   LoginResult = binding.login(username, password);
   // Process successful LoginResult
   ... 
} catch (LoginFault loginFault) { 
   ExceptionCode exCode = loginFault.getExceptionCode();
   if (exCode == ExceptionCode.PASSWORD_LOCKOUT) {
       // User login has exceeded number of failed password attempts
       // Provide details to user or log 
       String errMsg = loginFault.getMessage();
       ...
       // Exit and do not re-attempt to login with this user
       ...
   }
   if (exCode == ExceptionCode.INVALID_LOGIN) {
       // Invalid password or credentials
       // Provide details to user or log
       String errMsg = loginFault.getMessage();
       ...
       // Have user provide correct credentials and re-attempt login
       ...
   }
   // Process other possible errors
   ...
}
 

See Exception Codes in the SOAP API Developer’s Guide for a full list of possible error codes.

If you’re using a REST-based API and get a 400-level error when trying to log in, you can check the response data for the “errorCode” and “message” details. A JSON response might look something like:

 
{
 "message" : "Invalid username, password, security token",
 "errorCode" : "INVALID_LOGIN"
}
 

See Status Codes and Error Responses in the REST API Developer’s Guide for more details on REST API error responses.

 

Track Login Failures and Re-use Login Sessions Across Integration Jobs

In some scenarios it might not be possible to address login errors at the time of login failure. You might have several integration jobs running on independent systems that can’t rely on user interaction during errors. A login error will result in a failed integration job. However, there’s no way to correct or communicate that login error so that the next integration job can complete, resulting in many repeated login errors for each integration job.

In this scenario, you can use an external queue to track the currently in-use user login session. Each integration job can check this queue and re-use the already logged-in session. Additionally, if an un-recoverable login error occurs, a job can remove the session from the queue, or mark the session/user ID as no longer valid for log in. You can use this queue to communicate to the next job that the user login isn’t going to work, thereby making sure that subsequent integration jobs don’t continue trying to login using a login ID that will not work.

 

Getting and caching a session ID

You should get a session ID as part of the response of a successful login. Obtaining and re-using a session ID might even automatically be handled for you, if you are using something like the Force.com Web Services Connector (WSC). If you’re using a REST based Salesforce API, you’ll receive a session ID as part of your OAuth authentication process, which you should cache and re-use for subsequent transactions.

A session ID will expire after a configurable timeout period if there is no associated user activity, however it can be refreshed and re-used, rather than having to login and authenticate again.

 

Checking for expired session

You can check the response from transactions to determine if the session has expired or not.  If the session has expired, you’ll get a “Session expired or invalid” INVALID_SESSION_ID error in the response. Here’s a simple Java example using the SOAP API that catches an expired session exception:

 
try { 
   // Salesforce transaction using current session
   ... 
} catch (UnexpectedErrorFault uef) { 
   if (uef.ExceptionCode == ExceptionCode.INVALID_SESSION_ID) { 
       // Try and refresh the user session 
       ...
   } 
}
 

Refreshing the session ID

When a session ID expires, if you’re using OAuth to authenticate, you can request a token refresh using OAuth. Your client will send a OAuth POST request with the session ID and client ID and client secret (as defined by the connected app settings for your app/client) and receive a refreshed session ID you can use for new transactions.

See Understanding the Refresh Token Flow and Digging Deeper into OAuth for more details on working with OAuth and refreshing session IDs.

 

Verify API Access Permissions and Monitor API Limits

Even if the login username and password information is correct, a login can still fail when used for API access due to incorrect API permissions, or API limits for your organization.

If you’re attempting to connect to an organization that doesn’t support API access, you’ll get an API_DISABLED_FOR_ORG error. API access for an organization is controlled by Salesforce edition type. API Access is available for Enterprise, Unlimited, Performance and Developer edition organizations. Contact Salesforce support if you believe your organization should have API access and you’re getting an API_DISABLED_FOR_ORG error.

If you’re attempting to login as a user that doesn’t have API access, you’ll get an API_CURRENTLY_DISABLED (“API is disabled for this User”) error. In addition to Salesforce edition API access control, admins can further restrict API access by enabling or disabling the “API Enabled” setting for a user profile (under Settings, Manage Users, Profiles). Make sure any users that need API access to your organization are using a user profile that has API Enabled turned on.

Salesforce also sets limits on how many API calls (including programmatic logins) can be called per 24-hour period. This is based off the Salesforce edition type. If you exceed the number of calls per 24-hour period for your edition type, you might get a failed login indicating your request limit has been reached. The actual limits per edition type are documented in “API Usage Metering” under Implementation Considerations in the SOAP API Developer’s Guide.

 

Verify the Security Token

Salesforce provides additional validation of user credentials for API logins by requiring that a login provide a user ID, password, and a security token. Depending on how you’ve configured your Salesforce organization, you may have to include the security token as part of your login.

If you’re logging in for API access, you need to append the security token to your password when providing login credentials, otherwise you’ll get a LOGIN_MUST_USE_SECURITY_TOKEN error. However, if you’ve configured your org to use Trusted IP Ranges and are calling a login from a registered IP address, you do not need to append the security token.

Salesforce generates a security token for each user. Salesforce does not save the token for security reasons, and instead notifies the user of their token via email, so users are responsible for managing their security tokens. When a user changes their password, Salesforce will also generate a new security token and send a new email.

If a login is failing due to an invalid security token, the user might need to have Salesforce generate a new security token, by going to Settings, My Personal Information, Reset My Security Token. See Resetting Your Security Token for more details.

See “Security Token” in Security and the API in the SOAP API Developer’s Guide for more information on how security tokens are used in the login process.




promote demote