<p><img class="alignnone size-full wp-image-4464" src="https://flowgenius.in/wp-content/uploads/2026/01/Child-14-Cluster-10.png" alt="" /></p>
<p style="text-align: center;">Step by Step Guide to solve n8n Salesforce API Error Codes</p>
<p> </p>
<hr />
<p> </p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Who this is for:</strong> Automation engineers who use n8n to integrate with Salesforce and need deterministic handling of API failures. <strong>We cover this in detail in the</strong> <a href="https://flowgenius.in/n8n-api-integration-errors/">n8n API Integration Errors Guide.</a></p>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">Quick‑Fix Matrix</h2>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="border: 1px solid #ddd; padding: 13px;">Error Code</th>
<th style="border: 1px solid #ddd; padding: 13px;">HTTP Status</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">INVALID_FIELD</td>
<td style="border: 1px solid #ddd; padding: 13px;">400</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">MALFORMED_QUERY</td>
<td style="border: 1px solid #ddd; padding: 13px;">400</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">UNAUTHORIZED</td>
<td style="border: 1px solid #ddd; padding: 13px;">401</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">INSUFFICIENT_ACCESS</td>
<td style="border: 1px solid #ddd; padding: 13px;">403</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">REQUEST_LIMIT_EXCEEDED</td>
<td style="border: 1px solid #ddd; padding: 13px;">429</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">SERVER_UNAVAILABLE</td>
<td style="border: 1px solid #ddd; padding: 13px;">503</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">INVALID_SESSION_ID</td>
<td style="border: 1px solid #ddd; padding: 13px;">401</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">DUPLICATE_VALUE</td>
<td style="border: 1px solid #ddd; padding: 13px;">400</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY</td>
<td style="border: 1px solid #ddd; padding: 13px;">400</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">QUERY_TIMEOUT</td>
<td style="border: 1px solid #ddd; padding: 13px;">408</td>
</tr>
</tbody>
</table>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="border: 1px solid #ddd; padding: 13px;">Typical Trigger</th>
<th style="border: 1px solid #ddd; padding: 13px;">Quick Fix</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Field does not exist on the object</td>
<td style="border: 1px solid #ddd; padding: 13px;">Verify the exact API name in <strong>Setup → Object Manager</strong></td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">SOQL syntax error</td>
<td style="border: 1px solid #ddd; padding: 13px;">Test the query in <strong>Developer Console</strong>; escape reserved words</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">OAuth token missing or expired</td>
<td style="border: 1px solid #ddd; padding: 13px;">Add a <strong>Refresh Token</strong> node or re‑authenticate the credential</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Profile lacks CRUD permission</td>
<td style="border: 1px solid #ddd; padding: 13px;">Grant <em>Read/Write</em> on the object or switch to an integration user</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">API‑call quota exceeded</td>
<td style="border: 1px solid #ddd; padding: 13px;">Insert a <strong>Rate‑Limit</strong> node or batch with <em>Delay</em></td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Salesforce service outage</td>
<td style="border: 1px solid #ddd; padding: 13px;">Add exponential‑back‑off retry logic; monitor status.salesforce.com</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Session revoked (e.g., password change)</td>
<td style="border: 1px solid #ddd; padding: 13px;">Re‑authenticate; enable OAuth2 refresh flow</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Unique‑field violation</td>
<td style="border: 1px solid #ddd; padding: 13px;">Use <em>Upsert</em> or deduplicate before <em>Create</em></td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Trigger/workflow blocks DML</td>
<td style="border: 1px solid #ddd; padding: 13px;">Disable offending trigger or adjust its criteria</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Long‑running SOQL query</td>
<td style="border: 1px solid #ddd; padding: 13px;">Reduce selected fields, add selective filters</td>
</tr>
</tbody>
</table>
<blockquote style="margin: 2em 0; padding-left: 1em; border-left: 4px solid #eee;">
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>EEFA Note</strong> – Wrap every Salesforce node in a <strong>Try/Catch</strong> sub‑workflow that logs <code>$node["Salesforce"].json</code> to a persistent store. This preserves the raw <code>errorCode</code> needed for automated remediation.</p>
</blockquote>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">1. Why Salesforce Returns Structured Error Codes in n8n</h2>
<p><strong>If you encounter any</strong> <a href="/n8n-google-sheets-api-errors">n8n google sheets api errors</a><strong> resolve them before continuing with the setup.</strong></p>
<p style="margin-bottom: 2em; line-height: 1.9;">n8n forwards the raw JSON body from Salesforce’s REST API. The payload always contains:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto; line-height: 1.9;">{
"errorCode": "INVALID_FIELD",
"message": "No such column 'Foo__c' on entity 'Account'."
}
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>errorCode</strong> – Canonical identifier defined by Salesforce (stable across API versions).<br />
<strong>message</strong> – Human‑readable description for logging; not reliable for programmatic handling.</p>
<p style="margin-bottom: 2em; line-height: 1.9;">n8n surfaces both fields in the node’s <strong>Error</strong> output, enabling precise branching.</p>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">2. Mapping Error Codes to n8n Design Patterns</h2>
<p><strong>If you encounter any</strong> <a href="/n8n-s3-upload-error-handling">n8n s3 upload error handling</a><strong> resolve them before continuing with the setup.</strong></p>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="border: 1px solid #ddd; padding: 13px;">n8n Pattern</th>
<th style="border: 1px solid #ddd; padding: 13px;">Relevant Error Code(s)</th>
<th style="border: 1px solid #ddd; padding: 13px;">Recommended Node Setup</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Conditional Branch (<code>If</code>)</td>
<td style="border: 1px solid #ddd; padding: 13px;">INVALID_FIELD, MALFORMED_QUERY</td>
<td style="border: 1px solid #ddd; padding: 13px;">Compare <code>$node["Salesforce"].json.errorCode</code> and route to a *Fix Field* sub‑workflow</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Retry Loop (<code>Loop</code> + <code>Delay</code>)</td>
<td style="border: 1px solid #ddd; padding: 13px;">REQUEST_LIMIT_EXCEEDED, SERVER_UNAVAILABLE, QUERY_TIMEOUT</td>
<td style="border: 1px solid #ddd; padding: 13px;">Loop ≤ 3 attempts, delay = <code>2^attempt * 1000 ms</code></td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Token Refresh (<code>OAuth2 Refresh</code>)</td>
<td style="border: 1px solid #ddd; padding: 13px;">UNAUTHORIZED, INVALID_SESSION_ID</td>
<td style="border: 1px solid #ddd; padding: 13px;">Place before each Salesforce node; enable “Refresh on Failure”</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Deduplication (<code>Set</code> + <code>If</code>)</td>
<td style="border: 1px solid #ddd; padding: 13px;">DUPLICATE_VALUE</td>
<td style="border: 1px solid #ddd; padding: 13px;">Run a *Search* node first; on duplicate, switch to *Upsert*</td>
</tr>
</tbody>
</table>
<blockquote style="margin: 2em 0; padding-left: 1em; border-left: 4px solid #eee;">
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>EEFA Warning</strong> – Never rely on a generic “catch‑all” (<code>statusCode !== 200</code>). Distinct error codes demand distinct remediation; swallowing them causes silent data loss.</p>
</blockquote>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">3. Building a Robust “Insert Contact” Workflow</h2>
<p style="margin-bottom: 2em; line-height: 1.9;">Below is a production‑ready n8n workflow that inserts a Contact and gracefully handles duplicates, token expiry, and rate limits. The JSON is split into logical 4‑line snippets for readability.</p>
<h3 style="margin-bottom: 45px; line-height: 1.3;">3.1 Trigger – runs every 5 minutes</h3>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto; line-height: 1.9;">{
"name": "Trigger",
"type": "n8n-nodes-base.cron",
"parameters": { "cronExpression": "0 */5 * * * *" }
}
</pre>
<h3 style="margin-bottom: 45px; line-height: 1.3;">3.2 Salesforce Insert – creates the Contact</h3>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto; line-height: 1.9;">{
"name": "Salesforce Insert",
"type": "n8n-nodes-base.salesforce",
"parameters": {
"operation": "create",
"object": "Contact",
"additionalFields": {
"Email": "={{$json.email}}",
"FirstName": "={{$json.firstName}}",
"LastName": "={{$json.lastName}}"
}
},
"credentials": { "salesforceOAuth2Api": "Salesforce Credential" }
}
</pre>
<h3 style="margin-bottom: 45px; line-height: 1.3;">3.3 Error Router – detects duplicate records</h3>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto; line-height: 1.9;">{
"name": "Error Router",
"type": "n8n-nodes-base.if",
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$node[\"Salesforce Insert\"].json.errorCode}}",
"operation": "contains",
"value2": "DUPLICATE_VALUE"
}
]
}
}
}
</pre>
<h3 style="margin-bottom: 45px; line-height: 1.3;">3.4 Upsert Contact – updates if duplicate exists</h3>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto; line-height: 1.9;">{
"name": "Upsert Contact",
"type": "n8n-nodes-base.salesforce",
"parameters": {
"operation": "upsert",
"object": "Contact",
"upsertKey": "Email",
"additionalFields": {
"FirstName": "={{$json.firstName}}",
"LastName": "={{$json.lastName}}"
}
}
}
</pre>
<h3 style="margin-bottom: 45px; line-height: 1.3;">3.5 Log Failure – persists unexpected errors</h3>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto; line-height: 1.9;">{
"name": "Log Failure",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://mylogservice.example.com/err",
"method": "POST",
"jsonParameters": true,
"options": {
"body": {
"error": "={{$node[\"Salesforce Insert\"].json}}"
}
}
}
}
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">Workflow wiring – The Trigger feeds the Insert node. The Insert node’s <strong>main</strong> output connects to both the Error Router (for duplicate handling) and Log Failure (for successful inserts). The Error Router’s <strong>true</strong> branch points to Upsert Contact; the <strong>false</strong> branch can be extended with additional retry or alert logic.</p>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">4. Common Error Scenarios & Fix Checklists</h2>
<table style="border-collapse: collapse; width: 100%; margin-bottom: 2em;">
<thead>
<tr>
<th style="border: 1px solid #ddd; padding: 13px;">Scenario</th>
<th style="border: 1px solid #ddd; padding: 13px;">Error Code(s)</th>
<th style="border: 1px solid #ddd; padding: 13px;">Root Cause</th>
<th style="border: 1px solid #ddd; padding: 13px;">Fix Checklist</th>
</tr>
</thead>
<tbody>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Field name typo</td>
<td style="border: 1px solid #ddd; padding: 13px;">INVALID_FIELD</td>
<td style="border: 1px solid #ddd; padding: 13px;">API name mismatch</td>
<td style="border: 1px solid #ddd; padding: 13px;">• Open <strong>Setup → Object Manager → Fields & Relationships</strong><br />
• Copy exact API name<br />
• Update node field mapping</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">SOQL syntax error</td>
<td style="border: 1px solid #ddd; padding: 13px;">MALFORMED_QUERY</td>
<td style="border: 1px solid #ddd; padding: 13px;">Missing commas, wrong relationship syntax</td>
<td style="border: 1px solid #ddd; padding: 13px;">• Validate query in <strong>Developer Console</strong><br />
• Escape reserved words with backticks (`\“)<br />
• Follow <code>SELECT Id, Name FROM Account</code> pattern</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Permission issue</td>
<td style="border: 1px solid #ddd; padding: 13px;">INSUFFICIENT_ACCESS, UNAUTHORIZED</td>
<td style="border: 1px solid #ddd; padding: 13px;">Integration user lacks CRUD or required OAuth scopes</td>
<td style="border: 1px solid #ddd; padding: 13px;">• Grant *Read/Write* on the object via profile/permission set<br />
• Ensure OAuth scopes include <code>api</code> and <code>refresh_token</code></td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">API limits hit</td>
<td style="border: 1px solid #ddd; padding: 13px;">REQUEST_LIMIT_EXCEEDED</td>
<td style="border: 1px solid #ddd; padding: 13px;">> 15 000 calls/24 h (or per‑license limits)</td>
<td style="border: 1px solid #ddd; padding: 13px;">• Insert a <strong>Rate‑Limit</strong> node<br />
• Consolidate bulk operations using the **Salesforce Bulk** node</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Session revoked</td>
<td style="border: 1px solid #ddd; padding: 13px;">INVALID_SESSION_ID</td>
<td style="border: 1px solid #ddd; padding: 13px;">Password change, IP range change, or manual revocation</td>
<td style="border: 1px solid #ddd; padding: 13px;">• Re‑authenticate the credential<br />
• Enable **OAuth2 Refresh Token** flow in the connected app</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Unique field conflict</td>
<td style="border: 1px solid #ddd; padding: 13px;">DUPLICATE_VALUE</td>
<td style="border: 1px solid #ddd; padding: 13px;">Duplicate external ID on insert</td>
<td style="border: 1px solid #ddd; padding: 13px;">• Switch to **Upsert**<br />
• Pre‑check existence with a *Search* node</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Trigger blocks DML</td>
<td style="border: 1px solid #ddd; padding: 13px;">CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY</td>
<td style="border: 1px solid #ddd; padding: 13px;">Apex trigger or workflow prevents operation</td>
<td style="border: 1px solid #ddd; padding: 13px;">• Disable offending trigger or adjust its criteria</td>
</tr>
<tr>
<td style="border: 1px solid #ddd; padding: 13px;">Long‑running query</td>
<td style="border: 1px solid #ddd; padding: 13px;">QUERY_TIMEOUT</td>
<td style="border: 1px solid #ddd; padding: 13px;">Inefficient SOQL (no filters, too many fields)</td>
<td style="border: 1px solid #ddd; padding: 13px;">• Select only needed fields<br />
• Add selective WHERE clauses<br />
• Consider indexing the filter fields</td>
</tr>
</tbody>
</table>
<blockquote style="margin: 2em 0; padding-left: 1em; border-left: 4px solid #eee;">
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>EEFA Tip</strong> – For high‑volume integrations, prefer the **Bulk API** (up to 10 000 records per batch). Its error object (<code>batchInfo</code>) contains <code>state</code> and <code>errorMessage</code> fields you can poll for <code>BULK_API_ERROR</code>.</p>
</blockquote>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">5. Debugging Checklist (Practical)</h2>
<ol style="margin-bottom: 2em; line-height: 1.9;">
<li>Capture raw payload – Add a **Set** node: <code>errorPayload = $node["Salesforce"].json</code>.</li>
<li>Log externally – Use an **HTTP Request** node to POST the payload to Datadog, Sentry, etc.</li>
<li>Validate credentials – Click **Test** in the credential dialog; confirm <code>api</code> scope is present.</li>
<li>Confirm API version – n8n defaults to v52.0; some codes (e.g., <code>FIELD_CUSTOM_VALIDATION_EXCEPTION</code>) differ across versions. Align with your org’s *API Version* setting.</li>
<li>Check field‑level security – Even with object access, FLS can trigger <code>INVALID_FIELD</code>.</li>
<li>Subscribe to Salesforce status – Add a **Webhook** node that alerts on 5xx responses from <code>status.salesforce.com</code>.</li>
</ol>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">6. Frequently Asked Questions</h2>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Q: Does n8n expose the full list of Salesforce error codes?</strong><br />
A: Yes. Every code returned by the REST API is passed unchanged in the node’s *Error* output. Use the tables above as a starter; the official Salesforce docs enumerate all codes.</p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Q: Can I automatically retry on <code>REQUEST_LIMIT_EXCEEDED</code>?</strong><br />
A: Absolutely. Wrap the Salesforce node in a **Loop** node with a **Delay** (<code>2^$index * 1000 ms</code>) and set the loop condition to <code>$node["Salesforce"].json.errorCode === "REQUEST_LIMIT_EXCEEDED"</code>.</p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Q: How do I differentiate <code>UNAUTHORIZED</code> from <code>INVALID_SESSION_ID</code>?</strong><br />
A: Both return HTTP 401, but <code>errorCode</code> distinguishes them. <code>UNAUTHORIZED</code> usually signals missing OAuth scopes; <code>INVALID_SESSION_ID</code> indicates an expired or revoked token.</p>
<p style="margin-bottom: 2em; line-height: 1.9;"><strong>Q: Is there a way to translate error codes to user‑friendly messages?</strong><br />
A: Yes. Create a **Set** node with a mapping object, then reference it via an expression:</p>
<pre style="background: #fafafa; padding: 20px; border: 1px solid #e0e0e0; overflow: auto; line-height: 1.9;">{
"INVALID_FIELD": "Check field names in your Salesforce object.",
"MALFORMED_QUERY": "Review SOQL syntax."
}
</pre>
<p style="margin-bottom: 2em; line-height: 1.9;">Use <code>{{ $json[ $node["Salesforce"].json.errorCode ] }}</code> to retrieve the friendly text.</p>
<hr style="margin: 55px 0;" />
<h2 style="margin-bottom: 45px; line-height: 1.3;">Conclusion</h2>
<p style="margin-bottom: 2em; line-height: 1.9;">Salesforce’s structured <code>errorCode</code> values give you deterministic control inside n8n workflows. By:</p>
<ol style="margin-bottom: 2em; line-height: 1.9;">
<li>Parsing the <code>errorCode</code> from the node’s Error output,</li>
<li>Routing each code to a purpose‑built sub‑workflow (conditional, retry, token refresh, or deduplication), and</li>
<li>Logging the raw payload for observability,</li>
</ol>
<p style="margin-bottom: 2em; line-height: 1.9;">you eliminate silent failures, respect API limits, and keep integrations resilient in production. Apply the tables, snippets, and checklist above to any n8n‑Salesforce flow, and your automations will recover gracefully from the full spectrum of Salesforce API errors.</p>

Step by Step Guide to solve n8n Salesforce API Error Codes
Who this is for: Automation engineers who use n8n to integrate with Salesforce and need deterministic handling of API failures. We cover this in detail in the n8n API Integration Errors Guide.
Quick‑Fix Matrix
| Error Code |
HTTP Status |
| INVALID_FIELD |
400 |
| MALFORMED_QUERY |
400 |
| UNAUTHORIZED |
401 |
| INSUFFICIENT_ACCESS |
403 |
| REQUEST_LIMIT_EXCEEDED |
429 |
| SERVER_UNAVAILABLE |
503 |
| INVALID_SESSION_ID |
401 |
| DUPLICATE_VALUE |
400 |
| CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY |
400 |
| QUERY_TIMEOUT |
408 |
| Typical Trigger |
Quick Fix |
| Field does not exist on the object |
Verify the exact API name in Setup → Object Manager |
| SOQL syntax error |
Test the query in Developer Console; escape reserved words |
| OAuth token missing or expired |
Add a Refresh Token node or re‑authenticate the credential |
| Profile lacks CRUD permission |
Grant Read/Write on the object or switch to an integration user |
| API‑call quota exceeded |
Insert a Rate‑Limit node or batch with Delay |
| Salesforce service outage |
Add exponential‑back‑off retry logic; monitor status.salesforce.com |
| Session revoked (e.g., password change) |
Re‑authenticate; enable OAuth2 refresh flow |
| Unique‑field violation |
Use Upsert or deduplicate before Create |
| Trigger/workflow blocks DML |
Disable offending trigger or adjust its criteria |
| Long‑running SOQL query |
Reduce selected fields, add selective filters |
EEFA Note – Wrap every Salesforce node in a Try/Catch sub‑workflow that logs $node["Salesforce"].json to a persistent store. This preserves the raw errorCode needed for automated remediation.
1. Why Salesforce Returns Structured Error Codes in n8n
If you encounter any n8n google sheets api errors resolve them before continuing with the setup.
n8n forwards the raw JSON body from Salesforce’s REST API. The payload always contains:
{
"errorCode": "INVALID_FIELD",
"message": "No such column 'Foo__c' on entity 'Account'."
}
errorCode – Canonical identifier defined by Salesforce (stable across API versions).
message – Human‑readable description for logging; not reliable for programmatic handling.
n8n surfaces both fields in the node’s Error output, enabling precise branching.
2. Mapping Error Codes to n8n Design Patterns
If you encounter any n8n s3 upload error handling resolve them before continuing with the setup.
| n8n Pattern |
Relevant Error Code(s) |
Recommended Node Setup |
Conditional Branch (If) |
INVALID_FIELD, MALFORMED_QUERY |
Compare $node["Salesforce"].json.errorCode and route to a *Fix Field* sub‑workflow |
Retry Loop (Loop + Delay) |
REQUEST_LIMIT_EXCEEDED, SERVER_UNAVAILABLE, QUERY_TIMEOUT |
Loop ≤ 3 attempts, delay = 2^attempt * 1000 ms |
Token Refresh (OAuth2 Refresh) |
UNAUTHORIZED, INVALID_SESSION_ID |
Place before each Salesforce node; enable “Refresh on Failure” |
Deduplication (Set + If) |
DUPLICATE_VALUE |
Run a *Search* node first; on duplicate, switch to *Upsert* |
EEFA Warning – Never rely on a generic “catch‑all” (statusCode !== 200). Distinct error codes demand distinct remediation; swallowing them causes silent data loss.
3. Building a Robust “Insert Contact” Workflow
Below is a production‑ready n8n workflow that inserts a Contact and gracefully handles duplicates, token expiry, and rate limits. The JSON is split into logical 4‑line snippets for readability.
3.1 Trigger – runs every 5 minutes
{
"name": "Trigger",
"type": "n8n-nodes-base.cron",
"parameters": { "cronExpression": "0 */5 * * * *" }
}
3.2 Salesforce Insert – creates the Contact
{
"name": "Salesforce Insert",
"type": "n8n-nodes-base.salesforce",
"parameters": {
"operation": "create",
"object": "Contact",
"additionalFields": {
"Email": "={{$json.email}}",
"FirstName": "={{$json.firstName}}",
"LastName": "={{$json.lastName}}"
}
},
"credentials": { "salesforceOAuth2Api": "Salesforce Credential" }
}
3.3 Error Router – detects duplicate records
{
"name": "Error Router",
"type": "n8n-nodes-base.if",
"parameters": {
"conditions": {
"string": [
{
"value1": "={{$node[\"Salesforce Insert\"].json.errorCode}}",
"operation": "contains",
"value2": "DUPLICATE_VALUE"
}
]
}
}
}
3.4 Upsert Contact – updates if duplicate exists
{
"name": "Upsert Contact",
"type": "n8n-nodes-base.salesforce",
"parameters": {
"operation": "upsert",
"object": "Contact",
"upsertKey": "Email",
"additionalFields": {
"FirstName": "={{$json.firstName}}",
"LastName": "={{$json.lastName}}"
}
}
}
3.5 Log Failure – persists unexpected errors
{
"name": "Log Failure",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://mylogservice.example.com/err",
"method": "POST",
"jsonParameters": true,
"options": {
"body": {
"error": "={{$node[\"Salesforce Insert\"].json}}"
}
}
}
}
Workflow wiring – The Trigger feeds the Insert node. The Insert node’s main output connects to both the Error Router (for duplicate handling) and Log Failure (for successful inserts). The Error Router’s true branch points to Upsert Contact; the false branch can be extended with additional retry or alert logic.
4. Common Error Scenarios & Fix Checklists
| Scenario |
Error Code(s) |
Root Cause |
Fix Checklist |
| Field name typo |
INVALID_FIELD |
API name mismatch |
• Open Setup → Object Manager → Fields & Relationships
• Copy exact API name
• Update node field mapping |
| SOQL syntax error |
MALFORMED_QUERY |
Missing commas, wrong relationship syntax |
• Validate query in Developer Console
• Escape reserved words with backticks (`\“)
• Follow SELECT Id, Name FROM Account pattern |
| Permission issue |
INSUFFICIENT_ACCESS, UNAUTHORIZED |
Integration user lacks CRUD or required OAuth scopes |
• Grant *Read/Write* on the object via profile/permission set
• Ensure OAuth scopes include api and refresh_token |
| API limits hit |
REQUEST_LIMIT_EXCEEDED |
> 15 000 calls/24 h (or per‑license limits) |
• Insert a Rate‑Limit node
• Consolidate bulk operations using the **Salesforce Bulk** node |
| Session revoked |
INVALID_SESSION_ID |
Password change, IP range change, or manual revocation |
• Re‑authenticate the credential
• Enable **OAuth2 Refresh Token** flow in the connected app |
| Unique field conflict |
DUPLICATE_VALUE |
Duplicate external ID on insert |
• Switch to **Upsert**
• Pre‑check existence with a *Search* node |
| Trigger blocks DML |
CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY |
Apex trigger or workflow prevents operation |
• Disable offending trigger or adjust its criteria |
| Long‑running query |
QUERY_TIMEOUT |
Inefficient SOQL (no filters, too many fields) |
• Select only needed fields
• Add selective WHERE clauses
• Consider indexing the filter fields |
EEFA Tip – For high‑volume integrations, prefer the **Bulk API** (up to 10 000 records per batch). Its error object (batchInfo) contains state and errorMessage fields you can poll for BULK_API_ERROR.
5. Debugging Checklist (Practical)
- Capture raw payload – Add a **Set** node:
errorPayload = $node["Salesforce"].json.
- Log externally – Use an **HTTP Request** node to POST the payload to Datadog, Sentry, etc.
- Validate credentials – Click **Test** in the credential dialog; confirm
api scope is present.
- Confirm API version – n8n defaults to v52.0; some codes (e.g.,
FIELD_CUSTOM_VALIDATION_EXCEPTION) differ across versions. Align with your org’s *API Version* setting.
- Check field‑level security – Even with object access, FLS can trigger
INVALID_FIELD.
- Subscribe to Salesforce status – Add a **Webhook** node that alerts on 5xx responses from
status.salesforce.com.
6. Frequently Asked Questions
Q: Does n8n expose the full list of Salesforce error codes?
A: Yes. Every code returned by the REST API is passed unchanged in the node’s *Error* output. Use the tables above as a starter; the official Salesforce docs enumerate all codes.
Q: Can I automatically retry on REQUEST_LIMIT_EXCEEDED?
A: Absolutely. Wrap the Salesforce node in a **Loop** node with a **Delay** (2^$index * 1000 ms) and set the loop condition to $node["Salesforce"].json.errorCode === "REQUEST_LIMIT_EXCEEDED".
Q: How do I differentiate UNAUTHORIZED from INVALID_SESSION_ID?
A: Both return HTTP 401, but errorCode distinguishes them. UNAUTHORIZED usually signals missing OAuth scopes; INVALID_SESSION_ID indicates an expired or revoked token.
Q: Is there a way to translate error codes to user‑friendly messages?
A: Yes. Create a **Set** node with a mapping object, then reference it via an expression:
{
"INVALID_FIELD": "Check field names in your Salesforce object.",
"MALFORMED_QUERY": "Review SOQL syntax."
}
Use {{ $json[ $node["Salesforce"].json.errorCode ] }} to retrieve the friendly text.
Conclusion
Salesforce’s structured errorCode values give you deterministic control inside n8n workflows. By:
- Parsing the
errorCode from the node’s Error output,
- Routing each code to a purpose‑built sub‑workflow (conditional, retry, token refresh, or deduplication), and
- Logging the raw payload for observability,
you eliminate silent failures, respect API limits, and keep integrations resilient in production. Apply the tables, snippets, and checklist above to any n8n‑Salesforce flow, and your automations will recover gracefully from the full spectrum of Salesforce API errors.
Very insightful post! I’ve been researching how statistical models like the Kara model can outperform traditional betting methods.
Integrating ELO ratings and ROI analysis is definitely the future of football
predictions. If anyone is interested in seeing how data-driven tips work in practice, I’ve been tracking some very interesting results lately.
Keep up the good work!
Wonderful put up, veгy informative.
I wonder whу the opposite spеcialists of this sector do not reaⅼіze
thiѕ. You should proceed your writing. I am sure,
you’ve a great readers’ base already!