Skip to content

How DICOM objects actually move

Tonight · ~25 min · read · energy: low · setup: none

From HTTP you expect “send a request, get a response”. Classic DICOM networking does not work that way, and the mismatch is why integrating with PACS feels alien to engineers. This lesson is the DIMSE model — the verbs, the roles, and the association — in the smallest form that lets you diagnose a real retrieve failure.

The anchor: Application Entities, not URLs

Classic DICOM objects move over the DIMSE protocol between Application Entities (AE). An AE is identified by an AE Title + host/port — not a URL. Two roles:

  • SCU (Service Class User) — the client that initiates an operation.
  • SCP (Service Class Provider) — the server that serves it.

A node is usually both: a PACS accepts stores as SCP and initiates queries as SCU. Before any operation, the two AEs negotiate an association and agree Presentation Contexts — which SOP Classes and Transfer Syntaxes they will use. You rarely write DIMSE by hand (pynetdicom and PACS tooling handle it), but you must know the verbs to read a failure log.

The verbs

Operation Verb What it does
C-STORE “send an object” Push an image/derived object to an SCP.
C-FIND “query” Search by keys (PatientID, StudyInstanceUID, Modality, date, …).
C-MOVE “retrieve (via move)” Tell a source SCP to send matching objects to a destination AE (third party).
C-GET “retrieve (to self)” Tell a source SCP to send matching objects back to me.
Q/R (Query/Retrieve) C-FIND + C-MOVE/C-GET The standard “find studies, then pull them” loop.
Modality Worklist (MWL) “what to scan” C-FIND against the worklist so the modality fetches the ordered study/patient.

The retrieve workflow, concretely

The everyday PACS interaction is Query/Retrieve. A workstation wants a study:

  1. C-FIND by keys (e.g. PatientID + StudyDate) → the PACS returns matching study/series/instance identifiers.
  2. C-MOVE (or C-GET) → the PACS sends the matching objects to a destination.

Lesson 3 explains why C-MOVE — the more common retrieve verb in real PACS — feels strange: it sends to a third party, not back to the asker. That single design choice is the source of most “I queried but nothing arrived” confusion.

Association setup, in one paragraph

When an SCU connects to an SCP, they negotiate an association: which SOP Classes (object types) and Transfer Syntaxes (encodings) both sides will use. This is why a “connection refused”-style failure in DICOM is often actually a presentation context rejection — the two sides could not agree on an object type or encoding, even though TCP connected. You will see this in pynetdicom logs as failed presentation contexts. The fix is configuration (enable the right SOP Classes / transfer syntaxes on the SCP), not networking.

Stop and think — then reveal

You C-FIND a study and get its identifiers back, so connectivity is fine. You then C-MOVE that study to your workstation AE, and nothing arrives — no error, no images. You used HTTP logic and expected the response to come back over the same connection. What did you misunderstand about C-MOVE?

C-MOVE does not send the images back to the asker. It tells the source SCP to open a separate association to a destination AE (named in the C-MOVE request) and C-STORE the images there. So two things must be true that HTTP intuition does not prepare you for: (1) your workstation must itself be running as an SCP listening for C-STORE, and (2) the PACS must be configured to send to your AE Title at your host/port. If the destination is unknown to the PACS, you get an explicit A801 (Failure); if it is known but the transfer fails (nothing listening, firewall, rejects, or the SCP cannot perform the sub-operations), the final response is a B000 Warning (some sub-operations ran and failed) or a Failure such as A702/Cxxx — never a silent 0000 Success. The case where nothing arrives with a genuine 0000 (Success) is an expectation mismatch: the images were delivered to a different named destination than your requesting process. Lesson 3 has the full status table.

What to retain

  1. Classic DICOM moves over DIMSE between Application Entities (AE Title + host/port), with SCU (client) and SCP (server) roles.
  2. Verbs: C-STORE (push), C-FIND (query), C-MOVE/C-GET (retrieve), Q/R (the loop), MWL (worklist).
  3. An association negotiates Presentation Contexts (SOP Classes + Transfer Syntaxes); many “connection” failures are really presentation-context rejections.
  4. C-MOVE sends to a third-party destination AE, not back to the asker — the source of lesson 3’s strangeness.

Next: that strangeness, made explicit — why C-MOVE is strange when you come from HTTP.