DICOM Basics - General Troubleshooting Tips and Techniques

Introduction

This is part of my series of articles on the DICOM standard. In this article, we'll cover practical troubleshooting techniques for diagnosing and resolving common DICOM communication issues. Whether you're dealing with failed associations, missing images, or query problems, these techniques will help you identify and fix the root cause.

DICOM integration can be challenging due to the many configuration parameters and the variety of vendor implementations. A systematic troubleshooting approach will save time and frustration.

The Troubleshooting Mindset

Before diving into specific issues, adopt these principles:

  • Start Simple: Verify basic connectivity before complex operations
  • One Change at a Time: Make single changes and test
  • Document Everything: Keep notes on what you've tried
  • Check Both Ends: Problems can be on either side of the connection
  • Read the Logs: DICOM systems usually have detailed logging

Common DICOM Issues

Most DICOM problems fall into these categories:

CategorySymptoms
Network/ConnectivityConnection refused, timeouts
Association NegotiationAssociation rejected, no matching contexts
Data TransferMissing images, corrupted data
Query/RetrieveNo results, incomplete results
ConfigurationWrong AE titles, ports, transfer syntaxes

Step 1: Verify Network Connectivity

Before troubleshooting DICOM-specific issues, verify basic network connectivity:

Check if the port is reachable:

# Test TCP connection to DICOM port
telnet <host> <port>

# Or use netcat
nc -zv <host> <port>

# Windows PowerShell
Test-NetConnection -ComputerName <host> -Port <port>

Check if the service is listening:

# On the server, check listening ports
netstat -an | grep <port>

# Linux
ss -tlnp | grep <port>

Common network issues:

  • Firewall blocking the DICOM port
  • Wrong IP address or hostname
  • VPN or network segmentation issues
  • Service not running on the expected port

Step 2: Verify with C-ECHO

C-ECHO (DICOM Verification) is the simplest DICOM operation. If C-ECHO fails, more complex operations will also fail.

Using DCMTK:

echoscu -v <host> <port> -aet <local_ae> -aec <remote_ae>

Using fo-dicom (in code):

var client = new DicomClient();
client.AddRequest(new DicomCEchoRequest());

try
{
    await client.SendAsync(host, port, false, localAe, remoteAe);
    Console.WriteLine("C-ECHO successful!");
}
catch (Exception ex)
{
    Console.WriteLine($"C-ECHO failed: {ex.Message}");
}

Interpreting C-ECHO results:

ResultMeaning
Success (0000)Basic connectivity works
Connection refusedPort not listening or firewall
Association rejectedAE title or configuration issue
TimeoutNetwork issue or server overloaded

Step 3: Check AE Title Configuration

AE (Application Entity) title mismatches are one of the most common issues:

  • AE titles are case-sensitive on most systems
  • Maximum 16 characters
  • Some systems require pre-registration of remote AE titles
  • Spaces may cause issues

Checklist:

□ Called AE Title matches the server's configured AE title exactly
□ Calling AE Title is registered/allowed on the server
□ No leading/trailing spaces
□ Correct case (PACS vs pacs vs Pacs)

Step 4: Analyze Association Rejections

When an association is rejected, the rejection reason provides clues:

Rejection ReasonMeaningSolution
Called AE Title Not RecognizedServer doesn’t know the called AECheck AE title spelling
Calling AE Title Not RecognizedClient not registeredRegister client AE on server
No Reason GivenConfiguration issueCheck server logs
Temporary CongestionServer overloadedRetry later
Limit of Associations ReachedToo many connectionsWait or increase server limit

Step 5: Check Presentation Context Negotiation

Each SOP Class and transfer syntax combination forms a presentation context. Both sides must agree:

Common presentation context issues:

Problem: No acceptable Presentation Context
Cause: Server doesn't support the requested SOP Class

Problem: No matching transfer syntax
Cause: Client and server don't share any transfer syntaxes

Problem: Abstract Syntax Not Supported
Cause: Server doesn't implement the service you're requesting

Solution approach:

  1. Check the Conformance Statement for supported SOP Classes
  2. Verify transfer syntax compatibility
  3. Try Implicit VR Little Endian (always supported)

Step 6: Troubleshooting C-STORE Issues

Images not arriving:

□ Check C-STORE response status (should be 0000)
□ Verify storage path/disk space on receiver
□ Check for SOP Class compatibility
□ Verify transfer syntax is accepted
□ Check receiver logs for errors

Images arrive but can’t be viewed:

□ Check pixel data transfer syntax
□ Verify decompression codec is available
□ Check for corrupted data in transfer
□ Verify mandatory DICOM tags are present

Step 7: Troubleshooting Query Issues

No query results:

□ Verify Query/Retrieve SOP Class is supported
□ Check query level (PATIENT, STUDY, SERIES, IMAGE)
□ Verify query attributes are indexed by the server
□ Check wildcard syntax (* vs ?)
□ Verify date format (YYYYMMDD)
□ Check for empty result vs. error response

Query returns too many or too few results:

□ Check matching keys in your query
□ Verify case sensitivity settings
□ Check date range syntax (20250101-20250131)
□ Review server-side query limits

Step 8: Check DICOM Logs

Most DICOM systems provide detailed logging. Key information to look for:

Association Level:
  - Association request received
  - Presentation contexts proposed/accepted
  - Association accepted/rejected with reason

Operation Level:
  - C-STORE/C-FIND/C-MOVE requests received
  - Status codes returned
  - Error messages

Data Level:
  - SOP Instance UIDs processed
  - Transfer syntaxes used
  - Data transfer completion status

Essential DICOM Testing Tools

DCMTK (DICOM Toolkit) is the most widely used open-source toolkit for DICOM troubleshooting. This section provides comprehensive examples for diagnosing and resolving DICOM issues.


DCMTK Installation

Before using DCMTK tools, you need to install the toolkit:

Linux (Debian/Ubuntu):

sudo apt-get install dcmtk

macOS (Homebrew):

brew install dcmtk

Windows:

Download pre-built binaries from the OFFIS DCMTK website or use package managers like Chocolatey:

choco install dcmtk

Verify installation:

dcmdump --version

echoscu - DICOM Verification (C-ECHO)

The echoscu command is the first tool to use when troubleshooting. It performs a DICOM C-ECHO, which is the simplest DICOM operation and verifies basic connectivity.

Basic usage:

echoscu <host> <port>

With AE titles (most common scenario):

echoscu -aet MY_SCU -aec PACS_SCP 192.168.1.100 104
ParameterDescription
-aetApplication Entity Title of the local application (calling AE)
-aecApplication Entity Title of the remote application (called AE)

Verbose output for troubleshooting:

echoscu -v -d 192.168.1.100 104 -aet MY_SCU -aec PACS_SCP
FlagDescription
-vVerbose mode - shows association details
-dDebug mode - shows PDU level details
-llSet log level (fatal, error, warn, info, debug, trace)

Example verbose output (successful):

I: Requesting Association
I: Association Accepted (Max Send PDV: 16372)
I: Sending Echo Request (MsgID 1)
I: Received Echo Response (Success)
I: Releasing Association

Example verbose output (failed - AE title not recognized):

I: Requesting Association
E: Association Rejected:
E:   Result: Rejected Permanent
E:   Source: Service User
E:   Reason: Called AE Title Not Recognized

Timeout configuration:

# Set association timeout to 30 seconds
echoscu --timeout 30 192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

# Set DIMSE timeout (time to wait for response)
echoscu --dimse-timeout 60 192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

Testing with specific transfer syntax:

# Propose only Implicit VR Little Endian
echoscu -x= 192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

Common echoscu error messages and solutions:

Error MessageLikely CauseSolution
Association Rejected: Called AE Title Not RecognizedServer doesn’t recognize the called AEVerify -aec matches server’s configured AE title exactly
Association Rejected: Calling AE Title Not RecognizedClient AE not registered on serverRegister your AE title on the server
Connection refusedNo service listening on portVerify server is running and port is correct
TCP Initialization ErrorNetwork/firewall issueCheck network connectivity and firewall rules
Association AbortedServer terminated connectionCheck server logs for reason

storescu - Send DICOM Files (C-STORE)

The storescu command sends DICOM files to a DICOM server (SCP). It's essential for testing image storage workflows.

Basic usage - send a single file:

storescu 192.168.1.100 104 image.dcm -aet MY_SCU -aec PACS_SCP

Send multiple files:

storescu 192.168.1.100 104 *.dcm -aet MY_SCU -aec PACS_SCP

Send all files from a directory recursively:

storescu 192.168.1.100 104 --scan-directories --recurse /path/to/dicom/ -aet MY_SCU -aec PACS_SCP

Verbose output to see what’s happening:

storescu -v -d 192.168.1.100 104 image.dcm -aet MY_SCU -aec PACS_SCP

Example verbose output (successful):

I: Requesting Association
I: Association Accepted (Max Send PDV: 16372)
I: Sending file: image.dcm
I: Sending Store Request (MsgID 1, CT)
I: Received Store Response (Success)
I: Releasing Association

Propose specific transfer syntaxes:

# Send using JPEG Lossless compression
storescu -xs 192.168.1.100 104 image.dcm -aet MY_SCU -aec PACS_SCP

# Send using Explicit VR Little Endian only
storescu +x= 192.168.1.100 104 image.dcm -aet MY_SCU -aec PACS_SCP

# Send uncompressed (Implicit VR Little Endian)
storescu -x= 192.168.1.100 104 image.dcm -aet MY_SCU -aec PACS_SCP

Handle compressed images:

# Send compressed images as-is, preserving the original transfer syntax
# (the receiving SCP must support the compression scheme).
# Note: use dcmsend rather than storescu here — reliable on-the-fly
# decompression is a dcmsend feature; storescu's is experimental.
dcmsend --decompress-never 192.168.1.100 104 compressed.dcm -aet MY_SCU -aec PACS_SCP

# Alternatively, have DCMTK decompress on the fly and propose only
# uncompressed transfer syntaxes to the SCP.
dcmsend --decompress-lossy 192.168.1.100 104 compressed.dcm -aet MY_SCU -aec PACS_SCP

Test with different PDU sizes:

# Use smaller PDU size for problematic connections
storescu --max-pdu 16384 192.168.1.100 104 image.dcm -aet MY_SCU -aec PACS_SCP

Report detailed status:

storescu -v --report-file report.txt 192.168.1.100 104 *.dcm -aet MY_SCU -aec PACS_SCP

Common storescu issues and solutions:

IssueSymptomsSolution
SOP Class not supportedNo presentation context for: 1.2.840.10008.5.1.4.1.1.2Server doesn’t support this image type; check conformance statement
Transfer syntax mismatchNo acceptable Presentation ContextTry -x= to send uncompressed
File reading errorCannot open DICOM fileVerify file exists and is valid DICOM
Storage failureStatus A700 (Out of Resources)Server disk full or database issue

findscu - Query DICOM Server (C-FIND)

The findscu command queries a DICOM server for patient, study, series, or image information. It's critical for troubleshooting query/retrieve workflows.

Query levels:

# Patient level query
findscu -P -k QueryRetrieveLevel=PATIENT -k PatientName="*" \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

# Study level query (most common)
findscu -S -k QueryRetrieveLevel=STUDY -k PatientName="" -k StudyDate="" \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

# Series level query
findscu -S -k QueryRetrieveLevel=SERIES -k StudyInstanceUID="1.2.3..." \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

# Image level query
findscu -S -k QueryRetrieveLevel=IMAGE -k SeriesInstanceUID="1.2.3..." \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP
FlagDescription
-PPatient Root Query/Retrieve Information Model
-SStudy Root Query/Retrieve Information Model
-WModality Worklist Information Model - FIND

Query by patient name with wildcards:

# Exact match
findscu -S -k QueryRetrieveLevel=STUDY -k PatientName="DOE^JOHN" \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

# Wildcard match (all patients starting with DOE)
findscu -S -k QueryRetrieveLevel=STUDY -k PatientName="DOE*" \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

# All patients (empty value = universal match)
findscu -S -k QueryRetrieveLevel=STUDY -k PatientName="" \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

Query by date range:

# Specific date (YYYYMMDD format)
findscu -S -k QueryRetrieveLevel=STUDY -k StudyDate="20250115" \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

# Date range
findscu -S -k QueryRetrieveLevel=STUDY -k StudyDate="20250101-20250131" \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

# From date onwards
findscu -S -k QueryRetrieveLevel=STUDY -k StudyDate="20250101-" \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

# Up to date
findscu -S -k QueryRetrieveLevel=STUDY -k StudyDate="-20250131" \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

Query by modality:

# Find all CT studies
findscu -S -k QueryRetrieveLevel=STUDY -k ModalitiesInStudy="CT" \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

# Find MR studies
findscu -S -k QueryRetrieveLevel=STUDY -k ModalitiesInStudy="MR" \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

Query with specific return keys:

# Return specific attributes in results
findscu -S -k QueryRetrieveLevel=STUDY \
    -k PatientName="" \
    -k PatientID="" \
    -k StudyDate="" \
    -k StudyTime="" \
    -k StudyDescription="" \
    -k StudyInstanceUID="" \
    -k NumberOfStudyRelatedSeries="" \
    -k NumberOfStudyRelatedInstances="" \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

Save query results to files:

# Save each result as a separate DICOM file
findscu -S -k QueryRetrieveLevel=STUDY -k PatientName="*" \
    -X --output-directory ./results \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

Verbose output for troubleshooting:

findscu -v -d -S -k QueryRetrieveLevel=STUDY -k PatientName="DOE*" \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

Example query output:

I: ---------------------------
I: Find Response: 1 (Pending)
I:
I: # Dicom-Data-Set
I: # Used TransferSyntax: Little Endian Explicit
I: (0008,0052) CS [STUDY]                              # QueryRetrieveLevel
I: (0010,0010) PN [DOE^JOHN]                           # PatientName
I: (0010,0020) LO [12345678]                           # PatientID
I: (0008,0020) DA [20250115]                           # StudyDate
I: (0020,000d) UI [1.2.840.113619.2.55.3.123456]       # StudyInstanceUID
I:
I: ---------------------------
I: Find Response: 2 (Success)
I:

Combined query examples:

# Find CT studies for patient DOE from January 2025
findscu -S -k QueryRetrieveLevel=STUDY \
    -k PatientName="DOE*" \
    -k StudyDate="20250101-20250131" \
    -k ModalitiesInStudy="CT" \
    -k PatientID="" \
    -k StudyInstanceUID="" \
    -k StudyDescription="" \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

Troubleshooting findscu issues:

ProblemPossible CauseSolution
No resultsWrong query levelEnsure QueryRetrieveLevel matches your query keys
No resultsAttribute not indexedCheck if PACS indexes the attribute you’re querying
No resultsCase sensitivityTry different case or use wildcards
No presentation contextQuery model not supportedTry -S instead of -P or vice versa
Partial resultsServer limitCheck server configuration for result limits

movescu - Retrieve DICOM Studies (C-MOVE)

The movescu command retrieves DICOM objects from a server. Unlike C-GET, C-MOVE instructs the server to send images to a specified destination.

Important: For C-MOVE to work, the destination AE must be:

  • Registered on the source server
  • Running and accepting connections
  • Reachable from the source server

Basic C-MOVE by Study Instance UID:

movescu -S -k QueryRetrieveLevel=STUDY \
    -k StudyInstanceUID="1.2.840.113619.2.55.3.123456" \
    -aet MY_SCU -aec PACS_SCP -aem DEST_SCP \
    192.168.1.100 104
ParameterDescription
-aetCalling AE title (your application)
-aecCalled AE title (the PACS)
-aemMove destination AE title (where to send images)

Retrieve at different levels:

# Retrieve entire study
movescu -S -k QueryRetrieveLevel=STUDY \
    -k StudyInstanceUID="1.2.3..." \
    -aet MY_SCU -aec PACS_SCP -aem DEST_SCP 192.168.1.100 104

# Retrieve specific series
movescu -S -k QueryRetrieveLevel=SERIES \
    -k StudyInstanceUID="1.2.3..." \
    -k SeriesInstanceUID="1.2.3.4..." \
    -aet MY_SCU -aec PACS_SCP -aem DEST_SCP 192.168.1.100 104

# Retrieve specific image
movescu -S -k QueryRetrieveLevel=IMAGE \
    -k StudyInstanceUID="1.2.3..." \
    -k SeriesInstanceUID="1.2.3.4..." \
    -k SOPInstanceUID="1.2.3.4.5..." \
    -aet MY_SCU -aec PACS_SCP -aem DEST_SCP 192.168.1.100 104

Retrieve to local storage (using storescp):

First, start a local storage SCP:

# In terminal 1: Start receiving server
storescp -v --output-directory ./received 11112

# In terminal 2: Request the move
movescu -S -k QueryRetrieveLevel=STUDY \
    -k StudyInstanceUID="1.2.3..." \
    -aet MY_SCU -aec PACS_SCP -aem MY_SCU \
    --port 11112 192.168.1.100 104

Verbose output for troubleshooting:

movescu -v -d -S -k QueryRetrieveLevel=STUDY \
    -k StudyInstanceUID="1.2.3..." \
    -aet MY_SCU -aec PACS_SCP -aem DEST_SCP \
    192.168.1.100 104

Example successful output:

I: Requesting Association
I: Association Accepted (Max Send PDV: 16372)
I: Sending Move Request (MsgID 1)
I: Received Move Response 1 (Pending, 0 completed, 0 failed, 0 warning, 5 remaining)
I: Received Move Response 2 (Pending, 1 completed, 0 failed, 0 warning, 4 remaining)
...
I: Received Final Move Response (Success)
I: Releasing Association

Common movescu issues:

IssueError MessageSolution
Unknown destinationMove Destination UnknownRegister destination AE on source server
Destination unreachableUnable to connect to Move DestinationVerify destination SCP is running and network is accessible
No matching studiesStatus 0000 (Success) with zero completed sub-operationsAn empty result set is not an error; verify the StudyInstanceUID is correct
Partial failureStatus with failed count > 0Check sub-operation status codes

getscu - Retrieve Using C-GET

Unlike C-MOVE, C-GET retrieves images directly to the requesting application. This is useful when you can't configure the server with your AE title.

getscu -v -S -k QueryRetrieveLevel=STUDY \
    -k StudyInstanceUID="1.2.3..." \
    --output-directory ./received \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

Note: Not all PACS servers support C-GET. If it fails, use C-MOVE instead.


storescp - DICOM Storage Server (SCP)

The storescp command creates a simple DICOM storage server for receiving images. Essential for testing C-STORE and C-MOVE operations.

Basic storage server:

storescp 11112

With verbose output:

storescp -v 11112

Save received files:

# Save to specific directory
storescp --output-directory ./received 11112

# Custom filename pattern
storescp --output-directory ./received \
    --filename-extension .dcm \
    --sort-conc-studies series \
    11112

Set AE title:

storescp -aet MY_SCP 11112

Debug incoming associations:

storescp -v -d --debug 11112

Accept all transfer syntaxes:

storescp +xa 11112

Example output when receiving files:

I: Received Association Request
I:   Calling Application Entity: SENDING_AE
I:   Called Application Entity:  MY_SCP
I: Accepting Association
I: Received Store Request (MsgID 1)
I: Storing DICOM file: ./received/CT.1.2.840.113619.dcm
I: Sending Store Response (Status: Success)
I: Received Release Request

dcmdump - Inspect DICOM Files

The dcmdump command displays the contents of a DICOM file in human-readable format. It's indispensable for understanding what's in a DICOM file.

Basic dump:

dcmdump image.dcm

Example output:

# Dicom-File-Format

# Dicom-Meta-Information-Header
# Used TransferSyntax: Little Endian Explicit
(0002,0000) UL 196                                      #   4, 1 FileMetaInformationGroupLength
(0002,0001) OB 00\01                                    #   2, 1 FileMetaInformationVersion
(0002,0002) UI =CTImageStorage                          #  26, 1 MediaStorageSOPClassUID
(0002,0003) UI [1.2.840.113619.2.55.3.123456]           #  38, 1 MediaStorageSOPInstanceUID
(0002,0010) UI =LittleEndianExplicit                    #  20, 1 TransferSyntaxUID

# Dicom-Data-Set
# Used TransferSyntax: Little Endian Explicit
(0008,0016) UI =CTImageStorage                          #  26, 1 SOPClassUID
(0008,0018) UI [1.2.840.113619.2.55.3.123456]           #  38, 1 SOPInstanceUID
(0008,0020) DA [20250115]                               #   8, 1 StudyDate
(0008,0060) CS [CT]                                     #   2, 1 Modality
(0010,0010) PN [DOE^JOHN]                               #   8, 1 PatientName
(0010,0020) LO [12345678]                               #   8, 1 PatientID
...

Show specific tags only:

# Show only patient and study information
dcmdump +P 0010,0010 +P 0010,0020 +P 0020,000d image.dcm

# Using tag names
dcmdump +P PatientName +P PatientID +P StudyInstanceUID image.dcm

Show pixel data information:

dcmdump +P PixelData image.dcm

Search for a specific value:

dcmdump image.dcm | grep -i "patientname"

Dump to file:

dcmdump image.dcm > dump.txt

Show private tags:

dcmdump --print-all image.dcm

Short format (one line per tag):

dcmdump -M image.dcm

Dump sequence items expanded:

dcmdump +Ep image.dcm

dcmftest - Verify DICOM File Format

The dcmftest command quickly tests if a file is a valid DICOM file.

dcmftest image.dcm
# Output: yes (if valid DICOM)
# Output: no (if not valid DICOM)

Test multiple files:

for f in *.dcm; do echo -n "$f: "; dcmftest "$f"; done

dciodvfy - Validate DICOM IOD

The dciodvfy command (part of David Clunie's dicom3tools) validates DICOM files against the standard. It's excellent for checking compliance.

Note: This tool is from dicom3tools, not DCMTK, but is commonly used alongside DCMTK.

dciodvfy image.dcm

Example output:

Warning - Missing attribute Type 2 Required Element=<PatientBirthDate> Module=<Patient>
Warning - Value dubious for this VR - Retired Person Name form
Error - Missing attribute Type 1 Required Element=<Rows> Module=<ImagePixel>

dcmconv - Convert DICOM Transfer Syntax

The dcmconv command converts DICOM files between different transfer syntaxes.

Convert to Explicit VR Little Endian:

dcmconv +te input.dcm output.dcm

Convert to Implicit VR Little Endian:

dcmconv +ti input.dcm output.dcm

Convert to Big Endian (retired since 2011):

dcmconv +tb input.dcm output.dcm

Remove meta header:

dcmconv -f input.dcm output.dcm

Common transfer syntax conversions:

FlagTransfer Syntax
+tiImplicit VR Little Endian
+teExplicit VR Little Endian
+tbExplicit VR Big Endian (retired since 2011)

dcmcjpeg / dcmdjpeg - JPEG Compression

Compress to JPEG:

dcmcjpeg input.dcm output.dcm

Decompress JPEG:

dcmdjpeg compressed.dcm uncompressed.dcm

Compress with specific quality:

# JPEG Baseline (lossy)
dcmcjpeg +eb input.dcm output.dcm

# JPEG Lossless
dcmcjpeg +el input.dcm output.dcm

dcmodify - Modify DICOM Tags

The dcmodify command modifies DICOM file attributes. Useful for anonymization and fixing incorrect data.

Modify a single tag:

dcmodify -m "PatientName=ANONYMOUS" image.dcm

Modify multiple tags:

dcmodify -m "PatientName=ANONYMOUS" -m "PatientID=00000" image.dcm

Delete a tag:

dcmodify -e "PatientBirthDate" image.dcm

Insert a new tag:

dcmodify -i "(0010,0040)=M" image.dcm  # PatientSex

Modify without backup:

dcmodify -nb -m "PatientName=TEST" image.dcm

Generate new UIDs:

dcmodify --gen-all-new-uids image.dcm

Batch modify (use with caution):

for f in *.dcm; do
    dcmodify -nb -m "PatientName=ANONYMOUS" "$f"
done

img2dcm - Create DICOM from Images

The img2dcm command converts standard images (JPEG, PNG, BMP) to DICOM format.

Basic conversion:

img2dcm input.jpg output.dcm

With patient/study information:

img2dcm -k "PatientName=DOE^JOHN" \
        -k "PatientID=12345" \
        -k "StudyDescription=Test Study" \
        input.jpg output.dcm

DCMTK Troubleshooting Workflow

Here's a systematic workflow for DICOM troubleshooting using DCMTK:

1. Test basic connectivity:

# Simple echo test
echoscu -v 192.168.1.100 104 -aet MY_SCU -aec PACS_SCP

2. If echo fails, increase verbosity:

# Debug level output
echoscu -v -d 192.168.1.100 104 -aet MY_SCU -aec PACS_SCP 2>&1 | tee echo_debug.log

3. If sending files fails, check the file:

# Verify file is valid DICOM
dcmftest image.dcm

# Dump file contents
dcmdump image.dcm | head -100

# Check SOP Class
dcmdump +P SOPClassUID image.dcm

4. If query returns no results:

# Verbose query with wildcards
findscu -v -d -S -k QueryRetrieveLevel=STUDY -k PatientName="*" \
    192.168.1.100 104 -aet MY_SCU -aec PACS_SCP 2>&1 | tee query_debug.log

5. If C-MOVE fails:

# Start local receiver
storescp -v --output-directory ./test 11112 &

# Test move with verbose output
movescu -v -d -S -k QueryRetrieveLevel=STUDY \
    -k StudyInstanceUID="1.2.3..." \
    -aet MY_SCU -aec PACS_SCP -aem MY_SCU \
    --port 11112 192.168.1.100 104

Other Testing Tools

DVTk (GUI):

  • Visual association testing
  • Script-based validation
  • Detailed message analysis

Orthanc:

  • Use as a test PACS server
  • Web interface for viewing stored images
  • RESTful API for testing

Network Capture with Wireshark

For deep troubleshooting, capture network traffic:

1. Start Wireshark capture on DICOM port
2. Filter: tcp.port == 104 (or your DICOM port)
3. Reproduce the issue
4. Analyze the DICOM PDUs

Wireshark can decode DICOM protocol, showing:

  • Association request/accept/reject PDUs
  • Presentation contexts negotiated
  • DIMSE messages (C-ECHO, C-STORE, etc.)
  • Status codes and error information

Common Error Codes

Status CodeMeaningTypical Cause
0000SuccessOperation completed
FF00PendingMore results coming (C-FIND)
A700Out of ResourcesServer storage/memory issue
A900Identifier Does Not MatchQuery/move UID mismatch
C000Unable to ProcessMalformed or unsupported request
FE00CancelOperation cancelled

Troubleshooting Checklist

Network Layer:
  □ Port is open and reachable
  □ No firewall blocking traffic
  □ DNS/hostname resolves correctly

Configuration Layer:
  □ AE titles match exactly (case-sensitive)
  □ Port numbers are correct
  □ Remote AE is registered if required

DICOM Layer:
  □ C-ECHO succeeds
  □ SOP Classes are compatible
  □ Transfer syntaxes are compatible
  □ Query attributes are indexed

Application Layer:
  □ Disk space available
  □ Database connectivity
  □ Required services running

Best Practices for Avoiding Issues

  • Always test with C-ECHO first
  • Keep Conformance Statements accessible
  • Document all configuration settings
  • Implement comprehensive logging
  • Monitor disk space and database connections
  • Use consistent naming conventions for AE titles
  • Test after any software updates

Conclusion

DICOM troubleshooting requires a systematic approach, starting from basic network connectivity and working up through the DICOM protocol layers. The key is to isolate where the problem occurs - network, association negotiation, or data transfer - and then apply the appropriate diagnostic techniques.

Having the right tools (DCMTK, Wireshark, test servers) and understanding how to read logs and error codes will significantly speed up problem resolution. When in doubt, start with C-ECHO and work your way up to more complex operations.