A Mirth Connect channel that refuses to start is the most common non-network integration incident we see. Sometimes it happens after a deploy, sometimes after a Mirth restart, sometimes apparently out of nowhere. The symptom is usually familiar: channel sits in Deploying or Undeployed in the Dashboard, no messages flow, and the error shown in the UI is either truncated or cryptic.
Seven root causes cover about 95% of the cases we see in production. This guide walks through the full diagnosis ladder, names each of the seven, and gives the specific fix for each. It pairs with our MLLP connection refused guide — many channel-not-starting incidents are actually MLLP listener binding issues, and many MLLP refused incidents are actually a stopped channel.
If production is down, our Mirth Connect helpdesk responds in under 15 minutes. For a broader catalog of common problems and fixes, see our Mirth Connect issues and fixes page.
1. Channel Startup Lifecycle
A Mirth channel goes through several distinct steps when it starts. Understanding the sequence helps you name the failure.
- Load channel XML from database — Mirth reads the channel definition from the
d_channeltable. - Parse and validate — XML parsing, schema validation, basic sanity checks.
- Compile scripts — preprocessor, filter, transformer, postprocessor, response transformer scripts are compiled by the Rhino JavaScript engine.
- Initialize source — bind listener sockets, open file watchers, start database pollers.
- Initialize destinations — open connection pools, validate endpoints, load TLS material.
- Start message polling/listening — channel transitions to
Startedand begins accepting messages.
A failure at any of these steps prevents the channel from reaching Started. The error class tells you which step failed. For background on channels and sources/destinations see the Mirth Connect complete guide.
2. Emergency Recovery Procedure
If a production channel is down right now and clinical workflow depends on it, do these in order.
Step 1 — Capture the error (30 seconds)
Open the Administrator Dashboard. Note the channel state (Deploying, Undeployed, Errored) and any error text displayed. Screenshot it.
Step 2 — Tail the server log (1 minute)
tail -n 300 /opt/mirthconnect/logs/mirth.log | grep -E 'ERROR|WARN|Exception' -A 5Look for the stack trace near the channel name or channel ID. The top line of the stack trace is the exception class — that tells you which root cause category to focus on (sections 4–10).
Step 3 — Confirm the Mirth service itself is healthy (30 seconds)
sudo systemctl status mirth-connect
ps -ef | grep -i mcserverIf Mirth itself is crashed or out of memory, no channel will start. Restart Mirth and revisit. If the JVM is OOM-killed repeatedly, see our Java heap space error guide.
Step 4 — Try an Undeploy + Deploy cycle (2 minutes)
In the Administrator, Stop the channel (if possible), Undeploy it, wait 15 seconds, then Deploy. A stuck channel sometimes clears on redeploy if the underlying transient issue has resolved. If it does not clear, do not keep bouncing the channel — the root cause will not fix itself.
Step 5 — Fall back to the last-known-good export (3 minutes)
If the channel was modified recently and is now broken, import the previous export from your version control. This gets you back to a working channel in minutes rather than hours.
Step 6 — Escalate after 10 minutes
If these steps haven't recovered the channel and clinical workflow is impacted, escalate now. Continuing to debug alone past 10 minutes rarely ends well under time pressure.
3. Diagnosis Ladder
For non-emergency debugging, work through the ladder in order. Stop at the first step that reveals the root cause.
- Administrator shows a specific error — often enough to identify the cause.
- Server log stack trace — the exception class names the root cause category.
- Channel log (Dashboard → right-click channel → Channel Logs) — source- and destination-level events.
- JVM state — is the server healthy, or is it thrashing on GC or out of memory?
- Network state — for listener channels, is the TCP port actually available on this host?
- Dependency state — for channels that use JARs, JDBC drivers, or custom libraries, are they in place and the right version?
- Recent changes — what was changed in the last 24 hours on this channel, on Mirth, on the host, or on the network?
4. Root Cause 1 — BindException
The channel uses a listener-based source (MLLP, TCP, HTTP) and the port is unavailable.
Symptoms
- Stack trace contains
java.net.BindException: Address already in use. - Channel in
UndeployedorErroredstate after deploy. - Happens on startup or redeploy, never while running.
Diagnosis
# Find who owns the port
sudo lsof -i :6661
sudo ss -tlnp | grep 6661
# Check for TIME_WAIT sockets (prior instance still releasing)
sudo ss -tan | grep 6661Fix
- Another process owns the port — stop that process, or change Mirth's listener to a different port.
- Same Mirth channel is still in TIME_WAIT — wait 60 seconds and redeploy. Consider setting
SO_REUSEADDRon the listener configuration. - Wrong bind address — check channel source settings; to accept remote connections, bind to
0.0.0.0or a specific external IP, not127.0.0.1. - Privileged port (<1024) — either run Mirth as root (not recommended) or grant capabilities:
setcap 'cap_net_bind_service=+ep' $(which java).
Adjacent debugging for MLLP-specific BindException flavors is in the MLLP connection refused guide.
5. Root Cause 2 — Script Compile Errors
A transformer, filter, or preprocessor script has a syntax error, a reference to an undefined function, or a type error that only appears at compile time.
Symptoms
- Channel fails to deploy, state stuck at
Deployingbriefly then falls toErrored. - Server log contains
org.mozilla.javascript.EvaluatorExceptionor similar with a line number. - Recently modified — someone edited transformer code before the deploy.
Diagnosis
# Find the script error in the log
grep -A 10 'EvaluatorException\|ScriptException\|ReferenceError' \
/opt/mirthconnect/logs/mirth.log | tail -n 30The stack trace points to the script type and line number. In the Administrator, navigate to that script and look at the line.
Fix
- Fix the syntax error, typo, or undefined reference.
- If the change was made through the Administrator and is broken, revert by importing the last-known-good channel export.
- Consider adding a CI step that validates channel JavaScript syntax before deploy — a simple Rhino pass will catch most compile errors.
Prevention
- Never edit transformer code directly in production. Edit in dev, export, and promote.
- Version control every channel export. Diff before deploying changes.
- Use a linter on your JavaScript (ESLint with an ES5 profile works for Rhino's target language).
6. Root Cause 3 — Missing Dependency JARs
Channel code references a class from a JAR that is not on the Mirth classpath — either missing or the wrong version.
Symptoms
java.lang.ClassNotFoundExceptionorNoClassDefFoundErrorin server log.- Channel deploys on one host but not another — suggests classpath difference.
- Recent Mirth upgrade — bundled libraries changed, JDBC driver compatibility broke.
Diagnosis
# Find the missing class
grep -E 'ClassNotFoundException|NoClassDefFoundError' \
/opt/mirthconnect/logs/mirth.log | tail -n 20
# Inspect what is actually on the Mirth classpath
ls -la /opt/mirthconnect/custom-lib/
ls -la /opt/mirthconnect/server-lib/Fix
- Identify the JAR containing the missing class. Download it from Maven Central or the vendor.
- Drop it into
/opt/mirthconnect/custom-lib/on every Mirth host. - Update the channel's Library References in Administrator → Resources to include the new JAR.
- Restart Mirth so the classloader picks up the new library.
Prevention
- Document every JAR a channel depends on and maintain a script that copies them to each host on deploy.
- Pin JDBC driver versions — never rely on whatever was there before.
- After a Mirth upgrade, test every channel in staging before promoting to production.
7. Root Cause 4 — Deploy-Time Transformer Errors
Similar to script compile errors but caught later — the transformer uses a channel deploy script (global or per-channel) that fails while setting up channel-scoped state.
Symptoms
- Deploy script error in log — references
Deploy scriptorglobalMapinitialization. - Channel gets past compile but fails when the deploy script runs.
- Often references a resource the deploy script assumes exists: a file, a database, a network endpoint.
Diagnosis
Look at the channel-level Deploy script (Summary → Set Scripts → Deploy). Common failure patterns: reading a configuration file that doesn't exist on this host, calling an initialization endpoint that is down, loading a keystore that is in the wrong location.
Fix
- Wrap deploy-script resource access in try/catch with graceful degradation — the channel should still deploy if an optional resource is unavailable.
- Log the specific resource that failed so the next debug is faster.
- For required external resources, add preflight checks in your deploy pipeline.
8. Root Cause 5 — Datasource Connection Failure
The channel uses a JDBC source or destination (or a database reader/writer in a transformer), and Mirth cannot connect to the target database at deploy time.
Symptoms
- Stack trace contains
java.sql.SQLException,CommunicationsException, orPSQLException. - "Connection refused", "Login failed", or "Unknown database" in the error text.
- Happens on deploy and on redeploy consistently.
Diagnosis
# Test connectivity from the Mirth host
nc -vz db-host 5432
psql -h db-host -U mirth_user -d mirth_app
# Verify credentials and connection string match
grep -i 'datasource\|jdbc' /opt/mirthconnect/conf/*.propertiesFix
- Database down or unreachable — engage the DBA, confirm the target DB is up, fix network path.
- Credentials wrong — update the channel's JDBC settings; if using a secrets store, confirm the secret was rotated correctly.
- Driver missing — see Root Cause 3; add the JDBC driver JAR.
- TLS required on DB — append
?sslmode=requireor equivalent to the JDBC URL.
9. Root Cause 6 — TLS Initialization Errors
The channel uses MLLPS, HTTPS, or another TLS-enabled source/destination and TLS setup fails at deploy time.
Symptoms
javax.net.ssl.SSLException,UnrecoverableKeyException,KeyStoreExceptionin log.- "Keystore was tampered with or password was incorrect" — password/key mismatch.
- Happens after certificate rotation or a keystore change.
Diagnosis
# Verify keystore is readable and contents are sensible
keytool -list -v -keystore /opt/mirthconnect/conf/keystore.jks \
-storepass $(cat /run/secrets/mirth_keystore_pass) | head -n 50
# Check certificate validity
keytool -list -v -keystore /opt/mirthconnect/conf/keystore.jks \
-alias mirth-mllps | grep -i 'until'Fix
- Wrong password — update the password in the channel or in the secrets store it references.
- Missing alias — import the missing certificate into the keystore.
- Expired certificate — reissue and replace.
- Corrupt keystore file — restore from backup.
For deeper TLS hardening and rotation automation, see the SSL/TLS hardening guide.
10. Root Cause 7 — Channel XML Corruption
Less common but real — the channel definition in the database is malformed, usually from an interrupted write, a failed import, or a bad manual edit to exported XML.
Symptoms
- Stack trace contains
XMLStreamException,SAXParseException, or "unexpected end of file". - Channel that worked yesterday refuses to load today with a parse error.
- Administrator may fail to display the channel's Summary view.
Diagnosis
# Pull the channel XML out of the database for inspection
psql -d mirth_app -c "SELECT channel FROM d_channels WHERE id = '<channel-id>';" \
> broken-channel.xml
# Validate XML
xmllint --noout broken-channel.xmlFix
- Import the last-known-good channel export from version control. This is why you keep every channel in Git.
- If no clean export exists, hand-edit the XML to fix the specific parse error, then reimport.
- After restoring, verify every destination still points to the right endpoint — and that scripts, resources, and datasources are intact.
11. Long-Term Prevention Checklist
Teams that rarely see channel startup incidents have the following in place.
- ✓Channel export automation — every production channel exported to version control daily
- ✓Staging environment mirrors production — every channel deployed to staging first
- ✓Automated channel syntax checks in CI — catch script errors before they reach Mirth
- ✓Dependency JAR inventory documented per channel — which JARs, which versions, which location
- ✓Datasource connection health checks scheduled — confirm every DB/API reachable every hour
- ✓Channel deploy notification to a shared ops channel — everyone knows when channels change
- ✓Change-control on any channel touching production — no silent edits
- ✓Alerts on channel state changes — any channel going from started to stopped pages on-call
- ✓Channel XML backup before and after every edit — roll back in 30 seconds when a deploy breaks
- ✓Quarterly drill — rehearse channel restore from backup to validate the process works
For broader operational maturity, see the Mirth Connect issues and fixes catalog and the performance tuning guide.
12. When to Escalate
- Channel has been down for 30+ minutes and you cannot identify the root cause from the seven categories.
- Recovery requires touching the Mirth database directly — always a last resort.
- Multiple channels are failing simultaneously — suggests an infrastructure-wide problem, not a single-channel issue.
- The channel is clinical and downtime has patient-care consequences.
- You've restored from a previous export and the restored version has the same problem — suggests the issue is environmental, not in the channel definition.
Our Mirth helpdesk responds in under 15 minutes for production incidents. For ongoing support see our integration services and HL7 integration services across the USA.
13. Frequently Asked Questions
Why does my Mirth Connect channel stay in "Deploying" state forever?
Deploying never completes when a startup step is blocked — usually a TCP port bind waiting on a lock, a long-running script compile, or a datasource timeout. Check the server log for the specific channel around the deploy timestamp. The last line before the deploy stalled usually names the resource it was waiting on.
What does "Address already in use" mean in the Mirth log?
The channel's listener tried to bind to a TCP port that something else already holds. Either another process owns the port (find it with lsof -i :PORT), or a previous instance of the same channel is still releasing it (wait 60 seconds for TIME_WAIT to clear), or the bind address is wrong (0.0.0.0 vs 127.0.0.1).
Why does a channel deploy fine locally but fail in production?
Three common reasons: (1) the production host is missing a dependency JAR that exists in dev, (2) a production datasource credential is wrong or the DB is unreachable, (3) the production Mirth version differs slightly from dev and a feature your script uses is not available. Diff environments before assuming the channel itself is wrong.
How do I see the exact error when a channel fails to start?
Two places. The Administrator → Dashboard shows the channel state and usually a short error. The server log at /opt/mirthconnect/logs/mirth.log has the full stack trace — tail it while triggering the deploy. The combination almost always identifies the root cause within a minute or two.
Can a broken transformer script prevent a channel from starting?
Yes. Mirth compiles all scripts at deploy time — a syntax error, a reference to an undefined variable, or a typo in a function name causes the compile step to fail, which causes the whole channel deploy to fail. The server log will contain a Rhino/JavaScript error with the line number in the offending script.
What is the Undeploy / Redeploy sequence for a stuck channel?
From Dashboard, Stop the channel, then Undeploy it from the channel list. Wait 15 seconds, then Deploy again. If that doesn't clear the state, check the server log for the underlying error — a stuck channel always has a root cause that will show up in the log, and simply cycling the deploy won't fix a configuration problem.
How do I restore a channel from a previous export?
Administrator → Channels → Import Channel, select the exported XML, Mirth will replace the current definition after you confirm. Test by starting the channel and verifying it accepts/sends a single message. If the previous export is stored in Git, diff against the current definition before restoring so you know what changes you're undoing.
Why does my channel report "error" but no stack trace is visible?
The Mirth UI truncates long error messages. Check the full server log where the stack trace will be complete. Also check channel logs (Channel Logs from the Administrator) — source- and destination-level errors sometimes land there rather than in the global server log.
Can channel XML corruption happen silently?
It can, typically from an interrupted database write or a manual edit of exported XML that introduces malformed UTF-8 or unclosed tags. If a channel that worked yesterday refuses to start today with an XML parsing error, import the last-known-good export from version control. This is the main reason we keep every channel in Git.
When should I open a support case vs continue debugging?
Escalate if a channel has been down for 30+ minutes and none of the seven root causes in this guide match, or if recovery requires touching the underlying database, or if multiple channels are failing simultaneously which suggests an infrastructure-level problem. Our Mirth helpdesk responds in under 15 minutes for production issues.
Related Reading
- Mirth Connect: The Complete Guide
- Mirth Connect Installation Guide
- Common Mirth Connect Issues & Fixes
- Mirth Connect MLLP Connection Refused
- Mirth Connect Java Heap Space Error
- Mirth Connect Performance Tuning
- Mirth Connect SSL/TLS Hardening
- Mirth Connect Security & HIPAA Checklist
- HL7 Integration: The Complete Guide
- FHIR Integration Guide
- HL7 Integration Services USA