The CNE (Coded No Exceptions) data type was introduced in HL7 v2.5 alongside CWE to replace the deprecated CE composite. CNE is structurally identical to CWE — same 22 components in the same order — but it carries a stricter conformance contract: the code in CNE.1 must come from the value set bound to the field. CNE is used wherever HL7 wants to forbid local extensions: weight and volume units in BUI-5 / BUI-7, transport temperature units in BUI-12, administrative codes that drive downstream branching logic, and a handful of strictly-vocabulary-bound demographics fields.
Purpose
CNE exists because some coded fields cannot tolerate local variation. A unit of measure of g_local instead of g breaks every dose calculator downstream. A custom administrative-state code that no consumer recognizes silently corrupts a workflow. CNE codifies "this field is closed-vocabulary" at the data-type level so the engine, not the profile, enforces conformance.
The structural identity with CWE is deliberate: an engine that can serialize/deserialize CWE can do CNE with the same code path; the difference is a validator that runs after parsing and rejects out-of-set values rather than queuing them for curation.
The trade-off: CNE has the same 22 components as CWE, including Original Text and OID metadata, but in practice few CNE values use the alternate or second-alternate triplets. The point of CNE is precisely that there is no exception path; carrying a local code in CWE.4 would defeat the contract.
Component reference
Source: HAPI HL7v2 v2.8.1 javadocs — CNE. CNE has 22 components in v2.7+, separated by ^. Length is not published in the javadocs (—).
| Seq | Name | Data Type | Length | Req | Description |
|---|---|---|---|---|---|
| CNE.1 | Identifier | st | — | R | Primary code value. Must be from the bound value set — no exceptions. |
| CNE.2 | Text | st | — | O | Display text for CNE.1. |
| CNE.3 | Name of Coding System | id | — | R | Coding system for CNE.1. Required because CNE.1 is required. |
| CNE.4 | Alternate Identifier | st | — | C | Equivalent code from a second coding system, also constrained to its bound value set. |
| CNE.5 | Alternate Text | st | — | O | Display text for CNE.4. |
| CNE.6 | Name of Alternate Coding System | id | — | C | Coding system for CNE.4. |
| CNE.7 | Coding System Version ID | st | — | O | Version of CNE.3. |
| CNE.8 | Alternate Coding System Version ID | st | — | O | Version of CNE.6. |
| CNE.9 | Original Text | st | — | O | Original user text. Rarely populated in CNE because there is no free-text exception path. |
| CNE.10 | Second Alternate Identifier | st | — | O | Third code, also bound to a value set. |
| CNE.11 | Second Alternate Text | st | — | O | Display text for CNE.10. |
| CNE.12 | Name of Second Alternate Coding System | id | — | C | Coding system for CNE.10. |
| CNE.13 | Second Alternate Coding System Version ID | st | — | O | Version of CNE.12. |
| CNE.14 | Coding System OID | st | — | O | OID for CNE.3. |
| CNE.15 | Value Set OID | st | — | O | OID of the value set CNE.1 was drawn from. |
| CNE.16 | Value Set Version ID | dtm | — | O | Version of the value set. |
| CNE.17 | Alternate Coding System OID | st | — | O | OID for CNE.6. |
| CNE.18 | Alternate Value Set OID | st | — | O | Value set OID for CNE.4. |
| CNE.19 | Alternate Value Set Version ID | dtm | — | O | Version of CNE.18. |
| CNE.20 | Second Alternate Coding System OID | st | — | O | OID for CNE.12. |
| CNE.21 | Second Alternate Value Set OID | st | — | O | Value set OID for CNE.10. |
| CNE.22 | Second Alternate Value Set Version ID | dtm | — | O | Version of CNE.21. |
The composite is organized in triplets: primary (1–3), alternate (4–6), second alternate (10–12), each with its own version (7 / 8 / 13) and OID/value-set block (14–16 / 17–19 / 20–22).
Most-used components
- CNE.1 Identifier — the code; required.
- CNE.2 Text — display string for the code; recommended but not authoritative.
- CNE.3 Name of Coding System — required; without it the conformance check has no value set to validate against.
- CNE.4 / CNE.5 / CNE.6 — alternate triplet, rare in CNE but used for cross-vocabulary unit equivalents (e.g. UCUM
mLpaired with ISO unit code). - CNE.14 / CNE.15 — Coding System OID and Value Set OID. More commonly populated in CNE than CWE because OID-based binding is the unambiguous way to assert "this is the closed value set."
Where it's used
CNE shows up wherever HL7 binds a field to a closed value set. Representative fields:
- BUI-5 Weight Units
- BUI-7 Volume Units
- BUI-12 Transport Temperature Units
- OBR-44 Procedure Code (in profiles that bind tightly)
- OBR-45 Procedure Code Modifier
- DON-12 Donation Type (in donation segments)
- PID-8 Administrative Sex in v2.7+ profiles that re-typed it to CNE
- PV1-2 Patient Class in profiles that close the table
- SPM-4 Specimen Type (when bound to HL70487 strictly)
- TQ1-10 Conjunction (limited to
S,A,C,?) - ROL-3 Role (when bound strictly)
- MSH-15 / MSH-16 Accept / Application Acknowledgment Type
Version differences
- v2.5 — CNE introduced with 9 components (Identifier through Original Text), alongside CWE, as a replacement for CE.
- v2.6 — Second alternate triplet added (CNE.10–CNE.13).
- v2.7 — OID and Value Set metadata added (CNE.14–CNE.22), bringing the total to 22 components.
- v2.7.1 — Conformance language for "no exceptions" clarified; no structural changes.
- v2.8 / v2.8.1 / v2.8.2 — Structurally stable per the HAPI v2.8.1 javadocs. 22 components, same names and order as CWE.
Common mistakes
- Sending a local code in CNE.1. This is the central anti-pattern: CNE forbids exceptions. A receiver conforming to the standard will reject the message rather than route the value to curation.
- Confusing CNE with CWE in HAPI version-specific code. The classes are distinct (
...datatype.CNEvs...datatype.CWE) even though their components are identical; type checks and getter signatures differ. - Leaving CNE.3 empty. Unlike CWE, CNE.3 is required because CNE.1 is required.
- Populating CNE.9 Original Text with the user's free text in the hope it will pass through. CNE has no exception path; downstream validators that see CNE.9 without a valid CNE.1 will still reject.
- Treating components as repetitions — sending
g~kgin CNE.1. CNE is a single composite; multiple values require field-level repetition (rare for CNE because most CNE fields are non-repeating). - Down-casting CNE to CE on outbound and losing the OID metadata that pinned the value set.
- Using a coding-system version (CNE.7) that the receiver does not support. Unlike CWE, a version mismatch on CNE typically halts processing because the value-set binding is version-specific.
Examples
Minimal — required components only (CNE.1 + CNE.3):
mL^^UCUM
Three-component value — code + display + coding system:
mL^milliliter^UCUM
Administrative Sex in a CNE-typed profile:
F^Female^HL70001
Six-component value with alternate triplet (UCUM primary, ISO alternate):
mL^milliliter^UCUM^ml^millilitre^ISO+
Fully populated with OID metadata pinning the value set:
mL^milliliter^UCUM^^^^2013AB^^^^^^^2.16.840.1.113883.6.8^2.16.840.1.113883.3.88.12.80.27^20240101000000
In context — BUI-5 Weight Units and BUI-7 Volume Units in a BPS^O29 message:
BUI|1|W123426789012^^^RedCrossBB^DIN|E0336^RBC LR^HL70435|312|g^gram^UCUM|285|mL^milliliter^UCUM
In context — PID-8 Administrative Sex in a v2.7+ ADT^A04 profile that re-typed it as CNE:
MSH|^~&|ADT|MERCY|EHR|MERCY|20260610091500||ADT^A04|MSG00061|P|2.8.1
EVN|A04|20260610091500
PID|1||MR884412^^^MERCY^MR||TESTPATIENT^ALEX^Q||19720508|F^Female^HL70001
Common pitfall — local code in CNE.1 (violates the contract):
MERCY_F^Female (Mercy code)^MERCYLOCAL
A conformant receiver will reject this message. The correct fix is to either (a) emit F^Female^HL70001 or (b) re-profile the field to CWE.
Common pitfall — populating CNE.9 to smuggle free text:
^^^^^^^^Patient declined to specify
This breaks the required-CNE.1 contract; CNE has no free-text exception path.
FHIR mapping
The HL7 v2-to-FHIR Implementation Guide publishes the canonical ConceptMap for CNE:
Component-level mapping into CodeableConcept:
| HL7 v2 | FHIR target |
|---|---|
| CNE.1 Identifier | CodeableConcept.coding[0].code |
| CNE.2 Text | CodeableConcept.coding[0].display |
| CNE.3 Name of Coding System | CodeableConcept.coding[0].system (HL7 table name → URI) |
| CNE.4 Alternate Identifier | CodeableConcept.coding[1].code |
| CNE.5 Alternate Text | CodeableConcept.coding[1].display |
| CNE.6 Name of Alternate Coding System | CodeableConcept.coding[1].system |
| CNE.7 / CNE.8 / CNE.13 Coding System Version | CodeableConcept.coding[n].version |
| CNE.9 Original Text | CodeableConcept.text (rarely populated) |
| CNE.10–CNE.12 Second alternate | CodeableConcept.coding[2] |
| CNE.14 Coding System OID | resolves to CodeableConcept.coding[0].system URI |
| CNE.15 / CNE.16 Value Set OID + version | bound on the ValueSet; receiver enforces required binding |
When CNE carries a unit of measure (CNE.1 = mg, CNE.3 = UCUM), profiles often map it onto Quantity.code / Quantity.system rather than into a CodeableConcept. The IG ConceptMap addresses the CodeableConcept case; field-level mappings handle the Quantity case.
Engine considerations
- Strict validation — every inbound CNE must be validated against the bound value set. Engines that share a code path with CWE for parsing should diverge at the validation step: CWE routes unmapped codes to curation, CNE rejects them (or surfaces a hard error to the operator).
- OID-anchored binding — CNE.15 Value Set OID, when present, is the unambiguous binding. An engine that resolves the OID can validate without depending on profile metadata.
- Coding-system version sensitivity — CNE.7 mismatches with the engine's loaded value-set version can cause valid-looking codes to fail validation. Cache value-set versions per channel.
- No silent down-cast to CWE — although CNE and CWE are structurally identical, an outbound CNE must not be relaxed to CWE without an explicit profile change. The conformance contract is part of the field's meaning, not its serialization.
- FHIR-only downstream —
CodeableConceptdoes not encode "no exceptions" structurally; FHIR enforces this viaValueSetrequiredbinding strength. Engines crossing the v2 → FHIR boundary should preserve the binding strength in profile metadata, not assume the receiver knows the field is closed-vocabulary. - HAPI typing —
ca.uhn.hl7v2.model.v281.datatype.CNEexposes the same 22 typed accessors as CWE; treat the type as a marker for the validation contract.
How Vorro parses and produces CNE
Vorro treats CNE as a closed-vocabulary contract enforced inside the engine. On inbound:
- The validator resolves CNE.3 (and CNE.14 / CNE.15 if present) against a curated registry of bound value sets. CNE.1 is checked for membership before the message advances to routing.
- Out-of-set codes raise a hard error; the message does not silently pass. Operators see the rejected CNE value, the bound value set, and the channel.
- CNE.9 Original Text is preserved if populated but is not used as a fallback for failed validation — the rejection still fires.
- UCUM-bound fields (BUI-5 / BUI-7 / BUI-12, OBX-6 in profiles that close it) are validated against the UCUM registry directly, not just against value-set membership.
On outbound, Vorro emits CNE only when the channel is configured for a closed-vocabulary field. CNE.1, CNE.2, and CNE.3 are always populated together; CNE.14 / CNE.15 are added when the destination supports OID-based binding so the receiver can validate without depending on shared profile metadata.
Related pages
- CWE data type — Coded With Exceptions
- CE data type — Coded Element (legacy)
- CF data type — Coded Element with Formatted Values
