This guide covers the most common issues PACS administrators encounter.
Issue #1: Association Rejected - AE Title Not Recognized
Symptom: Modality cannot connect to PACS. Error: “Association rejected” or “Called AE Title not found”
Root Causes:
- AE Title mismatch (case-sensitive)
- AE Title not configured in PACS
- Extra spaces in AE Title
- Maximum length exceeded (16 characters)
Resolution:
public class AETitleValidator
{
public void ValidateAndFix(string aeTitle)
{
Console.WriteLine($"Validating AE Title: '{aeTitle}'");
// Check 1: Length
if (aeTitle.Length > 16)
{
Console.WriteLine($"AE Title too long: {aeTitle.Length} chars (max 16)");
Console.WriteLine($"Fix: Truncate to: '{aeTitle.Substring(0, 16)}'");
}
// Check 2: Leading/trailing spaces
if (aeTitle != aeTitle.Trim())
{
Console.WriteLine("Leading or trailing spaces detected");
Console.WriteLine($"Fix: Use '{aeTitle.Trim()}'");
}
// Check 3: Valid characters
if (!System.Text.RegularExpressions.Regex.IsMatch(aeTitle, @"^[A-Z0-9_ ]+$"))
{
Console.WriteLine("Invalid characters detected");
Console.WriteLine("AE Titles should only contain: A-Z, 0-9, space, underscore");
}
else
{
Console.WriteLine("AE Title format is valid");
}
}
}
PACS Configuration Steps:
- Log into PACS administration console
- Navigate to Network Configuration - Remote AE Titles
- Add the AE Title exactly as it appears on the device
- Verify IP address is correct
- Test connection using C-ECHO
Issue #2: Images Not Arriving at PACS
Symptom: Modality reports successful send, but images don’t appear in PACS
Root Causes:
- Network packet loss
- Firewall blocking return traffic
- PACS storage full
- Routing rules filtering the study
Diagnostic Script:
public class ImageArrivalDiagnostics
{
public void Diagnose(string modalityAE, string pacsAE, string pacsHost, int pacsPort)
{
Console.WriteLine("=== Image Arrival Diagnostics ===\n");
// Test 1: C-ECHO
Console.WriteLine("1. Testing connectivity (C-ECHO)...");
var echoService = new DicomVerificationService();
bool echoSuccess = echoService.PerformEcho(modalityAE, pacsAE, pacsHost, pacsPort);
if (!echoSuccess)
{
Console.WriteLine("C-ECHO failed - no connectivity");
return;
}
Console.WriteLine("C-ECHO successful\n");
// Test 2: Send test image
Console.WriteLine("2. Sending test image...");
string testImage = CreateTestImage();
var storageService = new DicomStorageService();
bool storeSuccess = storageService.StoreImage(
modalityAE, pacsAE, pacsHost, pacsPort, testImage);
if (!storeSuccess)
{
Console.WriteLine("C-STORE failed - check PACS logs");
return;
}
Console.WriteLine("C-STORE successful\n");
// Test 3: Query for the test image
Console.WriteLine("3. Querying PACS for test image...");
System.Threading.Thread.Sleep(5000); // Wait for processing
var queryService = new DicomQueryService();
var results = queryService.QueryStudies(
modalityAE, pacsAE, pacsHost, pacsPort,
patientName: "TEST^CONNECTIVITY"
);
if (results.Count > 0)
{
Console.WriteLine("Test image found in PACS");
Console.WriteLine("Issue is likely with specific studies or routing rules");
}
else
{
Console.WriteLine("Test image NOT found");
Console.WriteLine("Possible causes:");
Console.WriteLine(" - PACS routing rules filtering");
Console.WriteLine(" - Database synchronization delay");
}
}
private string CreateTestImage()
{
var creator = new DicomFileCreator();
var ds = creator.CreateCTImage("TEST^CONNECTIVITY", "CONNTEST001");
string testFile = Path.Combine(Path.GetTempPath(), "test.dcm");
creator.SaveDicomFile(ds, testFile);
return testFile;
}
}
Issue #3: Study Locked or In Use Error
Symptom: Cannot modify, delete, or re-send study. Error: “Study is locked”
Root Causes:
- Active query or retrieval operation
- Failed transaction not rolled back
- Orphaned lock from crashed process
Resolution Script:
public class StudyLockResolver
{
private SqlConnection dbConnection;
public void ResolveLock(string studyInstanceUID)
{
Console.WriteLine($"Resolving lock for study: {studyInstanceUID}\n");
var locks = CheckActiveLocks(studyInstanceUID);
if (locks.Count == 0)
{
Console.WriteLine("No active locks found");
return;
}
Console.WriteLine($"Found {locks.Count} active lock(s):");
foreach (var lockInfo in locks)
{
Console.WriteLine($"\nLock ID: {lockInfo.LockId}");
Console.WriteLine($"Process: {lockInfo.ProcessName}");
Console.WriteLine($"Started: {lockInfo.StartTime}");
Console.WriteLine($"Duration: {lockInfo.Duration}");
// If lock is older than 5 minutes, likely orphaned
if (lockInfo.Duration.TotalMinutes > 5)
{
Console.WriteLine("Lock appears orphaned (>5 minutes old)");
Console.Write("Release this lock? (y/n): ");
if (Console.ReadLine()?.ToLower() == "y")
{
ReleaseLock(lockInfo.LockId);
Console.WriteLine("Lock released");
}
}
}
}
private List<LockInfo> CheckActiveLocks(string studyInstanceUID)
{
var locks = new List<LockInfo>();
string query = @"
SELECT lock_id, process_name, lock_time,
DATEDIFF(MINUTE, lock_time, GETDATE()) as duration_minutes
FROM study_locks
WHERE study_instance_uid = @studyUID
AND lock_status = 'ACTIVE'";
using (var cmd = new SqlCommand(query, dbConnection))
{
cmd.Parameters.AddWithValue("@studyUID", studyInstanceUID);
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
locks.Add(new LockInfo
{
LockId = reader.GetInt32(0),
ProcessName = reader.GetString(1),
StartTime = reader.GetDateTime(2),
Duration = TimeSpan.FromMinutes(reader.GetInt32(3))
});
}
}
}
return locks;
}
private void ReleaseLock(int lockId)
{
string query = @"
UPDATE study_locks
SET lock_status = 'RELEASED', release_time = GETDATE()
WHERE lock_id = @lockId";
using (var cmd = new SqlCommand(query, dbConnection))
{
cmd.Parameters.AddWithValue("@lockId", lockId);
cmd.ExecuteNonQuery();
}
}
}
Issue #4: Duplicate Studies in PACS
Symptom: Same study appears multiple times
Root Causes:
- Multiple sends from modality
- Different accession numbers assigned
- UID reuse (non-compliant device)
Detection Script:
public class DuplicateStudyDetector
{
public void FindDuplicates(string patientID)
{
Console.WriteLine($"Searching for duplicates for Patient: {patientID}\n");
var studies = GetPatientStudies(patientID);
var potentialDuplicates = new List<List<StudyInfo>>();
// Group by modality and date (within 1 hour)
foreach (var study in studies)
{
var matchingGroup = potentialDuplicates.FirstOrDefault(g =>
g.First().Modality == study.Modality &&
Math.Abs((g.First().StudyDateTime - study.StudyDateTime).TotalHours) < 1
);
if (matchingGroup != null)
{
matchingGroup.Add(study);
}
else
{
potentialDuplicates.Add(new List<StudyInfo> { study });
}
}
// Report duplicates
var duplicateGroups = potentialDuplicates.Where(g => g.Count > 1);
if (!duplicateGroups.Any())
{
Console.WriteLine("No potential duplicates found");
return;
}
foreach (var group in duplicateGroups)
{
Console.WriteLine($"\n=== Potential Duplicate Group ===");
Console.WriteLine($"Modality: {group.First().Modality}");
Console.WriteLine($"Date: {group.First().StudyDateTime:yyyy-MM-dd}");
foreach (var study in group)
{
Console.WriteLine($" Study UID: {study.StudyInstanceUID}");
Console.WriteLine($" Accession: {study.AccessionNumber}");
Console.WriteLine($" Images: {study.NumberOfInstances}");
}
}
}
}
Issue #5: Character Encoding Problems
Symptom: Patient names display incorrectly with garbled characters
Root Causes:
- Missing Specific Character Set attribute
- Incorrect character set specified
- Encoding mismatch between systems
Resolution:
public class CharacterEncodingFixer
{
public void FixEncoding(string inputFile, string outputFile)
{
DicomDataSet ds = new DicomDataSet();
ds.Read(inputFile);
// Check current character set
string currentCharSet = ds[DicomTag.SpecificCharacterSet]?.Value?.ToString() ?? "";
Console.WriteLine($"Current Character Set: '{currentCharSet}'");
// Set to UTF-8 (ISO_IR 192)
ds[DicomTag.SpecificCharacterSet].Value = "ISO_IR 192";
// Re-encode string values if needed
string patientName = ds[DicomTag.PatientName]?.Value?.ToString();
if (!string.IsNullOrEmpty(patientName))
{
// Attempt to fix encoding issues
byte[] bytes = Encoding.GetEncoding("ISO-8859-1").GetBytes(patientName);
string corrected = Encoding.UTF8.GetString(bytes);
ds[DicomTag.PatientName].Value = corrected;
Console.WriteLine($"Patient Name: {patientName} -> {corrected}");
}
ds.Write(outputFile);
Console.WriteLine($"Fixed file saved to: {outputFile}");
}
}
Common Character Sets:
| Code | Description |
|---|---|
| ISO_IR 100 | Latin alphabet No. 1 |
| ISO_IR 101 | Latin alphabet No. 2 |
| ISO_IR 192 | UTF-8 |
| ISO 2022 IR 6 | ASCII |
| ISO 2022 IR 87 | Japanese (JIS X 0208) |
Troubleshooting Summary
| Issue | First Check | Common Fix |
|---|---|---|
| Association Rejected | AE Title configuration | Add AE Title to remote system |
| Images Missing | C-ECHO connectivity | Check firewall, routing rules |
| Study Locked | Lock table entries | Release orphaned locks |
| Duplicate Studies | Study matching criteria | Merge or delete duplicates |
| Character Issues | Specific Character Set | Set to ISO_IR 192 (UTF-8) |
Systematic troubleshooting helps resolve PACS issues quickly and efficiently.