FHIR search reserves a small set of characters for structural meaning inside a search value: comma, ampersand, pipe, dollar sign, and a couple of others. Values that carry any of them raw truncate silently at the first delimiter, and the resulting search runs against a partial value with no error surface. The site's FHIR search query auditor flags these encoding gaps. For the wider FHIR framing, more on FHIR workflow patterns has more.
The Reserved Set
- Comma (
,) — separates multiple OR values on the same parameter - Ampersand (
&) — separates parameters in the query string - Pipe (
|) — separates system from code in token searches - Dollar sign (
$) — begins an operation URL, reserved at the path level - Colon (
:) — begins a modifier suffix on a parameter name - Backslash and hash — reserved for other structural meanings
Any of those in a value has to be percent-encoded. The list is small; the impact is not.
The Silent Truncation
?name=O'Brien works. ?name=O'Brien,Smith is not a name that starts with O'Brien and ends with Smith — it is two separate name values, O'Brien and Smith, joined with an implicit OR. The server returns matches for either.
More insidious: ?name=Ampersand & Co truncates at the ampersand. The search runs against Ampersand with a trailing space, and the second half becomes a new parameter Co= that most servers ignore. The result set is wrong, no error surfaces.
For the wider picture of what quiet-wrong looks like, the FHIR searches that look correct but are wrong is the entry.
Token Search With System Codes
Token searches use pipe to separate system from code: ?code=http://loinc.org|1234-5. That is a pipe by design. If the code value itself contains a pipe — rare but possible in some coded value sets — it must be encoded to %7C.
More common: the system URL contains characters that need percent-encoding when placed in a URL path. ?code=urn:oid:2.16.840.1.113883.6.1|1234-5 may need the colons encoded depending on server implementation. Test both.
Encoding at the Client Layer, Not the URL Layer
The URL-encoding step has to happen at the FHIR-parameter layer, not at the URL-string layer. Encoding the whole URL after concatenation encodes the structural characters too — the comma that was supposed to separate values becomes an encoded comma inside a single value.
The correct pattern:
- Build parameter name and value strings
- Percent-encode reserved characters inside each value
- Join with
&and? - Do not re-encode the assembled URL
Skipping step 2 is the most common encoding bug. Doing step 2 twice is the second most common.
Multiple Values vs Multiple Parameters
?code=A,B means "code equals A OR B". ?code=A&code=B means "code equals A AND code equals B" — two separate parameters. The two are not equivalent, and the choice depends on the query intent.
Servers vary in how they handle repeated parameters. The safer form is ?code=A,B for OR semantics, per the spec. For the modifier semantics that stack on top, modifier stacking: :not, :in, :missing without foot-guns covers the surface.
What The Auditor Flags
The auditor at /dev-tools/audit-fhir-query/ walks the query string, identifies reserved characters in values, and flags un-encoded ones. It is a fast check before hitting a real server. For the broader rule set, linter rules to catch the ten most common search mistakes is the reference.
The Short Version
Encode reserved characters at the value layer, not the URL layer. Comma and ampersand are the biggest offenders. Multiple parameters with the same name are AND, comma-separated values are OR. The auditor catches most of it.

Sources
- HL7 canonical Search spec section on escaping reserved - HL7 canonical Search spec section on escaping reserved characters
