Skip to content

RTFM · Medical healthchecks

lb.saphira.dicom.echo: a wave across the room (C-ECHO)

DICOM's own hello: the check introduces itself with an AE title, asks the scanner or archive for a verification service, and waits for the acknowledgement. In hospital terms; the CT suite's front door is open and the PACS is answering, not just a TCP port.

Saphira Linux dragon mascot

What it proves

A complete DICOM association: negotiation opens with the right AE titles on both sides, the Verification Service Class (C-ECHO) executes, and the SCP acknowledges. Continuous-safe: read-only, cheap enough to run every few seconds forever.

This is the named capability "the DICOM service is reachable and speaking DICOM", and it never degrades to "the port is open": a TCP proxy in front of a dead PACS fails this check, exactly as it should.

How it works

The check drives echoscu from the DCMTK toolkit; the reference open-source DICOM SCU. The association timeout (-ta) is the shared LB_SAPHIRA_TIMEOUT, and the called/calling AE titles come from the configuration layer or the $6/$7 convenience positionals.

What the wrapper runs
echoscu -aet "$AET" -aec "$AEC" -ta "$LB_TIMEOUT" "$LB_REAL" "${LB_RPORT:-104}"

Configuration

Knobs
Variable / positionalDefaultMeaning
$6 or LB_SAPHIRA_DICOM_AECANY-SCPCalled AE title: the AE the SCP expects to be addressed by
$7 or LB_SAPHIRA_DICOM_AETSAPHIRA-HCCalling AE title: the check's own name
(target port)$4, else 104Many sites use 104, 11112 or 2762; all fine

AE titles are the DICOM equivalent of a door name: a modality may only accept callers addressing a specific title. Per-VIP titles live in the per-service conf file (e.g. dicom.echo/21.conf) so each virtual service can speak as the entity that site expects.

Wiring it up

ldirectord
# ldirectord.cf - DICOM pool over firewall mark 21
virtual = 21
    protocol = fwm
    scheduler = rr
    real = 192.168.20.21:104 gate 1
    real = 192.168.20.22:104 gate 1
    checktype = external
    checkcommand = "/var/lib/lb/saphira/lb.saphira.dicom.echo"
HAProxy
# haproxy.cfg
global
    external-check
backend dicom_pool
    mode tcp
    option external-check
    external-check command "/var/lib/lb/saphira/lb.saphira.dicom.echo"
    server pacs1 192.168.20.21:104 check inter 5s fall 3 rise 2

Run it by hand

Manual run
LB_SAPHIRA_DICOM_AEC=MODALITY-SCP \
  /var/lib/lb/saphira/lb.saphira.dicom.echo ct-pool 104 192.168.20.21 104
echo $?
# 0 = association accepted and C-ECHO acknowledged
# 1 = association refused, timeout, or DICOM rejected

Direct positional form for one-off tests: lb.saphira.dicom.echo 21 104 192.168.20.21 104 MODALITY-SCP SAPHIRA-HC

Failure modes

  • Association rejected: the SCP answered but refused the AE titles or the service: an acceptor-policy change, and the check caught it
  • Timeout: the classic PACS wedge: TCP accepts, DICOM never completes
  • exit 2 never occurs here: this check has full safe defaults

Did we miss something?

If this page left something unanswered, found an error, or there is another subject you would like documented, tell us. Saphira’s documentation grows from real problems people need to solve.

Send feedback or request a new section →

Prefer not to do it yourself?

Everything needed to do the work yourself is documented here and remains free; we charge for human time, not for withholding knowledge. Sometimes the missing resource is simply time. The same people who build Saphira can provide paid professional help with implementation, migration, troubleshooting and administration.

Ask about professional support →