Network

DICOM Query / Retrieve

Q/R is the workflow that lets a workstation pull a patient's priors from archive while they're being scanned. In practice it breaks constantly: firewall rules, AE title mismatches, level mismatches between the query and the retrieve, or a PACS that quietly limits matches to 500. Understanding the shape of Q/R turns most of these into single-line log-line fixes.

The four query levels

Every Q/R interaction happens at one of four levels, set by the Query/Retrieve Level attribute (0008,0052) in the query identifier:

  • PATIENT: all studies belonging to a patient
  • STUDY: a specific study (most common)
  • SERIES: a specific series within a study
  • IMAGE: a specific SOP Instance
One ladder, two entry points. The level in (0008,0052) decides how far down the hierarchy a query reaches. Patient Root starts at the top; Study Root, which almost every PACS and workstation actually uses, skips the patient tier and starts one rung lower.

The SOP Class UID on the Presentation Context also comes in two flavors: Patient Root (starts at PATIENT) and Study Root (starts at STUDY). Study Root is the overwhelming norm. Almost every PACS and workstation uses it, and it bypasses the need for well-maintained patient records.

C-FIND: the query

A C-FIND request is just a DICOM Data Set with match keys set. Non-empty values are match criteria; empty values (with VR set) are "I want this back in the response." The SCP interprets each field's VR-specific match semantics:

VRMatch typeNotes
UISingle-valueExact UID match only, no wildcards
DARange (-)20240101-20240131 matches anything in January 2024
TMRangeSame syntax as DA
LO / PN / SHWildcard (*, ?)SMITH* matches any name starting with SMITH (case sensitivity per SCP)
CSList (\\)CT\\MR matches either CT or MR modality

PN wildcard matching is notoriously inconsistent across PACS vendors. Some treat SMITH* as a prefix match on the family name only; others scan the whole PN value. If your wildcard queries return nothing you expected, test with a single-character query and compare against what the SCP's log reports.

Required vs optional match keys

Every SCP must support a baseline of "required" keys per level. For STUDY level those are Study Instance UID, Patient ID, Patient Name, Study Date, Study Time, Accession Number, Study Description, and Modalities in Study. Everything else is optional, and when a "vendor-required" key like Referring Physician's Name isn't supported, the SCP typically returns empty for that attribute without flagging an error, which makes silent Q/R bugs hard to spot.

C-MOVE: "send study X to AE Y"

C-MOVE has three AE titles in play:

  • The SCU making the request (e.g., the radiologist's workstation)
  • The SCP doing the retrieval (the PACS or archive)
  • The Move Destination AE, where the images get delivered

The Move Destination must be pre-configured on the SCP; its AE Title resolves (usually via a lookup table) to an IP address and port. The SCP then opens a new outbound association to the destination and C-STOREs the images.

The second association is the one that breaks. C-MOVE succeeds or fails in two places at once: the SCU sees the response, but the images travel on a connection the SCU never touches. A blocked port or an unrecognised AE Title on that leg still returns Success to the asker.

The "C-MOVE shows success but no images arrive" pattern: the SCP's new association to the destination fails: wrong IP in the SCP's lookup table, firewall blocking PACS → destination on the destination's inbound port, destination's AE title rejecting PACS as a sender. The C-MOVE response often still returns Success with Completed=N even when sub-ops silently failed. Check N-Completed vs N-Failed, and always check the destination's side.

C-GET: simpler but rarer

C-GET tunnels the C-STORE sub-operations back over the existing association. No second connection, no destination configuration, no firewall drama. But it requires both sides to have negotiated Presentation Contexts in both directions, which adds complexity to the original A-ASSOCIATE and is why many PACS don't bother supporting C-GET at all.

If you control both sides of the wire (e.g., an integration engine like Mirth Connect pulling from a PACS into a cloud archive), C-GET is usually the right call. If you're hooking up a third-party workstation or cross-enterprise, use C-MOVE.

Two connections versus one. Everything C-MOVE needs configuring is a consequence of that second association: a destination AE Title the SCP can resolve, and an inbound port open on the destination. C-GET trades that away for a negotiation both sides have to support.

DICOMweb: QIDO-RS + WADO-RS

Over HTTP, the modern equivalents are:

  • QIDO-RS: HTTP GET with query parameters. GET /studies?PatientID=12345&ModalitiesInStudy=CT returns a JSON or DICOM+JSON response with matching studies.
  • WADO-RS: HTTP GET to retrieve. GET /studies/{study-uid} returns the whole study as multipart/related with one DICOM part per instance.

QIDO-RS maps cleanly to C-FIND; WADO-RS maps to C-GET. If you're building a zero-footprint viewer, you're using DICOMweb end-to-end.

Next step

C-MOVE returning Success with nothing arriving?

That failure lives on the second association, where the SCU cannot see it. We debug retrieve paths across engines, modalities, and archives.

Medical imaging integration Validate a DICOM file

Glossary terms on this page

Browse the full healthcare IT glossary →

Explore further