The error occurs because the external endpoint requires specific headers in the API call to successfully retrieve an OAuth token. These headers might include an apiKey, client_id, client_secret, or other custom headers necessary for authentication.
When using Named Credentials in Salesforce, the custom headers specified in the External Credential configuration are intended to be used with the Named Credential endpoint. This means they are applied when making the actual API call to the external service, not when retrieving the OAuth token from the token endpoint.
However, the OAuth token request is a crucial step that occurs before any other API calls. It is the process where Salesforce exchanges credentials for an OAuth token, which is then used to authenticate subsequent API calls to the external service. Since the custom headers set in the External Credential are not applied to the token endpoint request, the necessary headers (such as apiKey) are missing during this step. As a result, the OAuth token cannot be fetched, leading to the System.CalloutException: Unable to fetch the OAuth token error.
This limitation means that while Named Credentials are a convenient way to manage authentication for API calls in Salesforce, they do not currently support passing custom headers to the token endpoint. Therefore, when custom headers are required for the token request, an alternative approach must be used.
To resolve this issue, there can be couple of ways -
a). Implement a custom solution using Apex code
This approach allows the necessary custom headers to be included in the token request and any subsequent API calls, ensuring that the external endpoint's requirements are met.
1 - Create a Custom Apex Class:
Example Apex Code :
Note - This is a code snippet, so use it or modify it as per your scenario.
public class CustomApiCallout {
public static HttpResponse makeCallout() {
HttpRequest req = new HttpRequest();
req.setEndpoint('https://your-external-endpoint.com/token');
req.setMethod('POST');
// Set custom headers
req.setHeader('Content-Type', 'application/json');
req.setHeader('apiKey', 'YOUR_API_KEY');
// Set the body of the request
req.setBody('{"client_id":"YOUR_CLIENT_ID","client_secret":"YOUR_CLIENT_SECRET"}');
Http http = new Http();
HttpResponse res = http.send(req);
if (res.getStatusCode() == 200) {
// Process the response
return res;
} else {
// Handle the error
throw new CalloutException('Failed to get OAuth token: ' + res.getStatus());
}
}
}
2 - Invoke the Custom Apex Class:
Example Invocation :
HttpResponse response = CustomApiCallout.makeCallout();
System.debug(response.getBody());
3 - Secure Your Credentials:
4 - Test the Configuration:
b). Use a proxy service
Create a middleware endpoint that adds required headers before forwarding requests to the token endpoint.
002471436

We use three kinds of cookies on our websites: required, functional, and advertising. You can choose whether functional and advertising cookies apply. Click on the different cookie categories to find out more about each category and to change the default settings.
Privacy Statement
Required cookies are necessary for basic website functionality. Some examples include: session cookies needed to transmit the website, authentication cookies, and security cookies.
Functional cookies enhance functions, performance, and services on the website. Some examples include: cookies used to analyze site traffic, cookies used for market research, and cookies used to display advertising that is not directed to a particular individual.
Advertising cookies track activity across websites in order to understand a viewer’s interests, and direct them specific marketing. Some examples include: cookies used for remarketing, or interest-based advertising.