I've successfully implemented the oAuth2 authentication process using the Web Server Flow of the REST API between my application and Salesforce, and it's working great when connecting with a Developer Edition type Salesforce account.

However, it's not working when trying to connect a test or prod environment type Salesforce account: I can't get an access token with the authorization code given by Salesforce since Salesforce gives me this error:

{"error_description":"authentication failure","error":"invalid_grant"}

Does anybody have an idea why it's not working ?

Here's what I've done:

Step 1 => OK => Redirect user to Salesforce

Step 2 => OK => User logs in

Step 3 => OK => User is redirected to our application with the authorization code

Step 4 => NOT OK => We request an access token using the authorization code given by Salesforce

We have tried it all (maybe not though :D): we have checked all the security configuration on our end and on the customer's end, we have checked for IP restrictions (no IP restriction is used), we have given our App "Full Access", but still no luck. We are receiving the authorization code which is encoded correctly and seems normal.

Does anybody have an idea why it's not working ?

Do you know if I need to validate our connected App before it can be used by test or prod type Salesforce accounts ?

Thanks a lot for all your help in advance. Cheers Quentin

NOTE : This is a duplicate of the following issue I guess, but it got no answer :( https://developer.salesforce.com/forums?id=906F00000009AFvIAM

EDIT 1 :

Here's the code I use ($instance is 'https://test.salesforce.com' in our case):

    $url = $instance . '/services/oauth2/token?format=json';
    $postFields = array(
        'code' => $code,
        'grant_type' => 'authorization_code',
        'client_id' => $this->clientId,
        'client_secret' => $this->clientSecret,
        'redirect_uri' => $this->redirectURL);
    // Create the CURL object.
    $handle = curl_init($url);
    curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($handle, CURLOPT_RETURNTRANSFER, TRUE);
    curl_setopt($handle, CURLOPT_FOLLOWLOCATION, TRUE);
    curl_setopt($handle, CURLOPT_POST, TRUE);
    curl_setopt($handle, CURLOPT_POSTFIELDS, $postFields);
  • Did you take a look at this post : salesforce.stackexchange.com/questions/5206/… how are you building your CURL, can you post your CURL
    – Rao
    Commented Jul 15, 2014 at 14:52
  • I have edited the question with my code :) Thanks for reaching out so quickly :) I have seen the post you're mentionning and it's not pertinent to my problem since I'm using the grant type "authorization_code" and not "password" :) Commented Jul 15, 2014 at 14:53
  • 4
    invalid_grant happens only for 2 reasons 1) when there is an IP restriction or login hour restriction 2) user credentials are not valid. Assuming 2) is provided right can you check if there is any user/ IP restriction
    – Rao
    Commented Jul 15, 2014 at 15:03
  • The following allowed IP range was already there for the user we're trying to use : "" to "". Also we have added the IP of our server as indicated in this link: help.salesforce.com/…. Furthermore we have disable IP restrictions on our end for the connected App. Do you think we have to add another configuration part for the IP restrictions bit ? Commented Jul 15, 2014 at 15:07
  • can you try to URLEncode the redirectURL, I saw somewhere that redirectURL has to be URLEncoded. when you say disabled IP restriction did you switch *IP Relaxation connected app setting to "Relax IP Restrictions"? Also not sure if you had a chance to look at this awesome cookbook : developer.force.com/cookbook/… ( I am not too aware of PHP syntax and your app seems to be talking PHP with salesforce all over)
    – Rao
    Commented Jul 15, 2014 at 17:22

3 Answers 3


I feel pretty dumb answering my own question but that may help somebody someday.

@Rao was totally right about that one so he deserves all the credit.

In my "Edit 1", I was wrong about the content of $instance.

It was not pointing to 'https://test.salesforce.com', it was pointing to 'https://login.salesforce.com' so it was normal to get an "authentication failure" error.

So if you're experiencing the same problem, do check the URL you're sending the request to.

  • Also look at the profiles assigned to the app.
    – martin
    Commented Aug 27, 2015 at 2:54
  • Man, I'd like to give you 70 up-votes for this one. Sometimes...
    – Johannes
    Commented Jun 4, 2019 at 21:22

Another thing that was not obvious to me from the documentation: the host URL is not just either "test.salesforce.com" or "login.salesforce.com". Mine is "na30.salesforce.com".

After I changed it from the default "test.salesforce.com" used in all the documentation I've read so far, OAuth worked, where before it would give me the "invalid grant" error.

I might have skipped some introductory materials...

PS: I don't have enough rep to post actual links. The above URLs all need the https:// prefix, of course.


It's important to check that the policies for the connected api you are using to authenticate with have Permitted Users equal All users may self-authorize.

To check, in lightning experience go to:

Setup > App Manager > yourConnectedAppName > click the down arrow on the far right > Manage > Edit Policies

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .