I am using PKCE ( proof key for code exchange ) flow in salesforce and trying to authenticate but getting below error

"error": "invalid_grant",
"error_description": "invalid code verifier"

Step 1 - Authorization code URL Below is the URL for the authorization code URL

https://login.salesforce.com/services/oauth2/authorize?client_id=3MVG97quAmFZJfVxm0NIj75FamFbSpgt8VgBNTKCprAD2ThUXvs8LfUwzunQZkdGzabnxu0w6ckZeX8rlGvG6&redirect_uri=https://www.sfdcpanther.com/&response_type=code&scope=full refresh_token&state=redirect_uri=https://www.sfdcpanther.com/&code_challenge=23cc1e54c8e06b1f8d69724fdd1fca1d5b0f38313c4b3bf9f1ca4cd7865b5816

I am using "23cc1e54c8e06b1f8d69724fdd1fca1d5b0f38313c4b3bf9f1ca4cd7865b5816" as a code challenge which is SHA256 of 73t874jdshfbhj value.

Step 2 - Access Token Code.

I am using the below body for the access token request.


I have tried 23cc1e54c8e06b1f8d69724fdd1fca1d5b0f38313c4b3bf9f1ca4cd7865b5816 and 73t874jdshfbhj both value for the code_verifier.

Please let me know if you have any suggestions for the same.

Edit 1

I also have tried to pass the code_challenge by base64Url Encode and still not working.


After some research, I was able to make it work. Adding the solution for all those who are looking to implement the PKCE flow for salesforce.

I got huge help from This link.

The salesforce document is missing one parameter which is code_challenge_method=S256 in the authorization URL.

Here is the full URL for the authorization request.


Once you will hit the above URL in your browser and after providing the consent you will be able to see the code and use the same code in the below request.


And you will be able to see the access token with additional details.

The doc says that the value for code_challenge must be base64Url-encode of code_verifer and salesforce does not provide a direct way to base64Url-encode so you can use the below code for the same.

public class PKCEOAuthHelper {

public static void printDetails(){
    String code_verifier  = generateRandomString(34);
    Blob sha256           = Crypto.generateDigest('SHA-256', Blob.valueOf(code_verifier));
    String code_challenge = base64URLencode(sha256);
    System.debug('**** code_verifier **** \n  '+code_verifier);
    System.debug('**** code_challenge **** \n '+code_challenge);

private static String base64URLencode(Blob input){
    String output = encodingUtil.base64Encode(input);
    output = output.replace('+', '-');
    output = output.replace('/', '_');
    while ( output.endsWith('=')){
        output = output.subString(0,output.length()-1);
    return output;

private static String generateRandomString(Integer len) {
    final String chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
    String randStr = '';
    while (randStr.length() < len) {
        Integer idx = Math.mod(Math.abs(Crypto.getRandomInteger()), chars.length());
        randStr += chars.substring(idx, idx+1);
    return randStr; 

Hope this will be helpful for the people who are willing to implement PKCE flow.

Note: - You need to replace the below values with your actual values.

  1. Client Id
  2. Client Secret
  3. Redirect URL
  4. Code Verifier
  5. Code Challenge

You can generate the code verifier and code challenge using the above code.

Thank You

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.