Base FHIR is permissive. Almost everything on Patient is optional. US Core tightens it into something interoperable, and that's where most "valid JSON, invalid resource" failures come from. Here's what US Core Patient actually demands, and the specific ways each requirement fails in production.
Required vs. must-support
US Core uses two levels of obligation, and conflating them is the first mistake:
- Mandatory (cardinality 1..*): the element must be present, or the resource is non-conformant. On US Core Patient that's
identifier(withsystemandvalue),name, andgender. - Must-support: your system must be able to populate and consume the element, and you must send it when you have the data.
birthDate,telecom,address,communication.language, and the race / ethnicity / birth-sex extensions fall here.
A resource missing a mandatory element fails outright. A resource missing must-support data is conformant only if you genuinely don't have that data, which a validator can't know. That's where human review matters.
The required elements, one by one
identifier (1..*, with system + value)
Every Patient needs at least one identifier, and each identifier needs both a system (a URI) and a value. The overwhelmingly common failure is a populated value with no system. That's the exact trap covered in Mapping HL7v2 ADT^A01 to a US Core Patient, where a v2 MRN has no URI and you have to inject your org's canonical system.
"identifier": [{
"system": "urn:oid:2.16.840.1.113883.19.5",
"value": "MRN12345"
}]
name (1..*)
At least one HumanName. US Core wants either family or given present (a data-absent-reason is allowed for unknowns). The failure mode: a name array that exists but contains an empty object, or a name carried only in text with no structured family/given.
gender (1..1)
Exactly one value from the administrative-gender value set: male, female, other, unknown. The failure is almost always a passed-through HL7v2 code (M, F) instead of the FHIR token. See the value-set gotcha in the ADT post.
The must-support elements that quietly fail
- birthDate. Present in most feeds, but watch the format. FHIR wants
YYYY-MM-DD(orYYYY/YYYY-MMpartials), never the v2YYYYMMDD. - telecom / address. Must-support, so send them when you have them. A common audit finding is dropping these during mapping because the source field was "optional."
- communication.language. Must use a BCP-47 code (
en,es), not a free-text language name. - US Core Race, Ethnicity, and Birth Sex extensions. These are extensions, not core elements, and they're the most-forgotten requirement. Payer and registry integrations frequently reject patients that omit them even though the resource is otherwise perfect.
Why "passes the parser" is not "passes US Core"
A JSON parser only checks syntax. The FHIR base schema only checks structure and data types. Neither knows that US Core requires gender, or that identifier.system is mandatory in the profile. So a resource can sail through both and still be rejected the moment it hits a US Core-aware endpoint. The only way to catch this before a partner does is to score the resource against the profile itself, counting which required and must-support elements are populated and flagging the gaps.
That coverage score is the same idea as the FHIRPath presence checks in FHIRPath expressions every implementer should know: each requirement reduces to an exists() over the resource.
Check coverage before you ship
Paste a Patient, score it against US Core, and you get a per-element breakdown of what's present, what's missing, and which gaps are hard failures versus must-support warnings. Nothing leaves your machine.