REQUIRED_FIELD_MISSING:Required fields are missing: [LastName]:LastName --
The short answer: every rejected row comes back with three things — a
status code (REQUIRED_FIELD_MISSING), a message, and usually the
field that caused it. Download the file of failed rows and group it by status code:
hundreds of rejected rows usually collapse into a handful of distinct problems. Fix those in
the source file, then reload only the failed rows.
Where the failed rows actually live
Each loading tool hides the detail in a different place.
- Bulk API 2.0 — request the job's failed results
(
/jobs/ingest/{jobId}/failedResults/): a CSV of the rejected rows with two extra columns in front of your original data,sf__Error(the status code and message) andsf__Id. It is the most useful artifact in a broken import, and the first thing to download. - Data Loader — writes a success file and an error file to the directory you chose. The error file is your failed rows plus the error text.
- Data Import Wizard — the person who started the import gets a status email, and admins can open Setup → Bulk Data Load Jobs (not available in Professional Edition).
How to read the line
A rejection is written left to right, and each part narrows the search:
INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST:bad value for restricted picklist field: US:CountryCode --
- The status code, up to the first colon — the category of failure, and the thing to search for and to group by.
- The message in the middle, which usually carries the offending value
(
US). This is often the useful part: a validation rule's message, for instance, was written by whoever built the rule. - The field at the end — the API name, not the label
(
CountryCode). Some codes name several.
Two rows failing on the same code and field are one bug, not two.
The five errors that produce most rejected rows
Each has a dedicated page, with the causes in the order worth checking.
The status codes, in one table
The codes you are most likely to meet on an insert or upsert. The middle column follows the definitions in Salesforce's own API status-code list, with the practical reading where the two differ.
| Status code | What it means | First thing to check |
|---|---|---|
INVALID_OR_NULL_FOR_RESTRICTED_PICKLIST |
You specified an invalid or null value for a restricted picklist. | The field's value set in Setup, and whether the value is active and on the record type. |
REQUIRED_FIELD_MISSING |
The call requires a field that was not specified. | The field named at the end of the message. Blank cells count as missing. |
DUPLICATE_VALUE |
A duplicate value was supplied for a field that must be unique. | Duplicates within your file first, then records already in the org. |
INVALID_CROSS_REFERENCE_KEY |
A record with the specified ID does not exist in the database. | The lookup or External Id column — a stale, sandbox, or misaligned parent value. |
MALFORMED_ID |
An ID must be either 15 characters, or 18 characters with a valid case-insensitive extension. | Truncation, a stray space, or an ID that lost characters in a CSV round trip. |
STRING_TOO_LONG |
The specified string exceeds the maximum allowed length. | The field's length in Object Manager against the longest value in your column. |
FIELD_CUSTOM_VALIDATION_EXCEPTION |
A validation rule — or an Apex addError() on a field — rejected the record. The text after the code is the rule's own error message. |
Read the message — an admin wrote it. Then find the rule in Setup. |
INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY |
The operation touches a record this one cross-references, and the logged-in user lacks permission on it. | Sharing and profile access on the parent record — not the file. |
CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY |
Defined as not having permission to create, update, or activate the record. In a data load, Salesforce's own troubleshooting points at Apex: a trigger hitting a governor limit or throwing during the save. | The class or trigger name in the message body, then permissions on the object. Reducing batch size is the usual first move. |
UNABLE_TO_LOCK_ROW |
A deadlock or timeout condition has been detected. | Parallel batches touching the same parent. Sort the file by parent ID and retry the failed rows. |
On UNABLE_TO_LOCK_ROW, Salesforce's own advice is structural: sort child records by
their parent so that rows sharing a parent do not land in different jobs competing for the same
lock. Smaller batches help for the same reason.
Errors that no file check can prevent
Several of the codes above are not file problems at all. No tool that reads your spreadsheet — ours included — can simulate what your org does when the record hits the database:
- Validation rules (
FIELD_CUSTOM_VALIDATION_EXCEPTION) — a formula in your org that can reference other fields, the owner, the running user, or a related record. - Triggers and Flows (
CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY) — Apex can reject a row for reasons that have nothing to do with the row. - Duplicate rules — a matching rule can block a perfectly valid row, based on records you cannot see from the file.
- Permissions and sharing
(
INSUFFICIENT_ACCESS_ON_CROSS_REFERENCE_ENTITY) — a function of who runs the load, not of what is in the file. - Row locks (
UNABLE_TO_LOCK_ROW) — a function of concurrency when the job runs.
The only honest strategy here is to load a small slice first — twenty rows, not twenty thousand — read what the org objects to, and adjust. Anyone promising to prevent these from a spreadsheet is guessing.
The pattern that saves the afternoon
What can be checked before a single record is written is everything the file itself determines: types, formats, picklist membership, lengths, ID shape, duplicates, required columns. These arrive in the thousands, and their cost is not the fix — each fix takes a minute. It is the loop: load, wait, download failures, fix three values, reload, discover four more. So, first:
- Map columns to API names, not labels.
- Check every value against the field's type — dates, numbers, checkboxes.
- Compare each picklist column's distinct values to the field's value set.
- Check lengths against the field definitions.
- Check for duplicates on any unique or External Id field, inside the file.
- Confirm no required field is blank on any row.
- Load a small slice, and only then the rest.
The loader matters too. The Data Import Wizard takes CSV only, caps at 50,000 records, and does not do Opportunities — see its limits and workarounds, or how to import Opportunities without it. Salesforce's own guidance is that any operation over 2,000 records is a good candidate for Bulk API 2.0 — which is Data Loader territory.
Catching the file-side errors in one pass
INQUA is built for this pre-flight step. It reads
.csv, .txt, .xlsx, and .xlsm directly — no
CSV conversion, so IDs and leading zeros survive — and shows a typed preview with an error on
every offending cell before anything is written. When the target comes from a Salesforce
object, it captures the accepted picklist values from your org's describe and flags values a
restricted picklist would reject. Its Map values editor lists the distinct
values in a source column next to a dropdown of the accepted ones, so you translate the whole
set in one screen instead of one error log at a time. Thirteen chainable transformations
handle the rest; see
the mapping and transformation options.
It will not save you from a validation rule, a Flow, or a duplicate rule — nothing that reads a file can. It removes the type, picklist, and formatting noise, so the errors you do get back are real org logic. Upload is refused while any cell error remains, and the load itself is a Bulk API insert or an External-Id upsert, double-confirmed: it never deletes, and never updates by record Id.
You can also skip Salesforce entirely — point it at your own load template and it writes a typed, validated workbook onto that template, header block and formatting intact. Reading Excel natively is the point of not going through CSV. Free during early access.