Resolving the 'Jira Connection Timeout' Error (504 Gateway Timeout / SocketTimeoutException)
Comprehensive guide to diagnosing and fixing Jira connection timeouts. Troubleshoot NGINX proxies, Tomcat server.xml, JVM heap exhaustion, and database bottlene
- Reverse Proxy (NGINX/Apache) misconfiguration often causes premature 504 Gateway Timeouts before Tomcat finishes processing.
- Exhausted Tomcat HTTP thread pools or insufficient connectionTimeout in server.xml lead to dropped connections.
- Long 'Stop-The-World' Garbage Collection (GC) pauses in the JVM freeze Jira, resulting in unresponsive endpoints.
- Database connection pool exhaustion (dbconfig.xml) blocks worker threads, causing cascading timeouts across the application.
| Method | When to Use | Time | Risk |
|---|---|---|---|
| Increase Proxy Timeout | When seeing 504 Gateway Timeout but Catalina logs show successful request completion. | 5 mins | Low |
| Tune Tomcat server.xml | When Jira drops connections during high concurrent user load or API spikes. | 15 mins | Medium (Requires Restart) |
| Adjust JVM Heap (setenv.sh) | When logs show OutOfMemoryError or GC logs indicate high pause times. | 30 mins | High (Requires careful calculation) |
| Increase DB Connection Pool | When thread dumps show threads waiting on database connections. | 20 mins | Medium (Requires DB capacity check) |
Understanding the Error
A 'Jira connection timeout' is a critical disruption that occurs when a client (such as a web browser, an external API integration, or a CI/CD pipeline) attempts to communicate with your Jira instance, but the server fails to return a response within the acceptable timeframe. Depending on the architecture of your deployment, this error manifests in several distinct ways. Users might see a generic ERR_CONNECTION_TIMED_OUT in their browsers, or a 504 Gateway Timeout originating from the load balancer. In application logs or API scripts, you may encounter java.net.SocketTimeoutException: Read timed out.
Because Jira Data Center and Server are complex Java applications running on Apache Tomcat, typically sitting behind a reverse proxy (like NGINX, HAProxy, or Apache HTTP Server) and backed by a relational database (PostgreSQL, MySQL, Oracle, or SQL Server), a timeout can stem from a bottleneck at any of these layers. Troubleshooting requires a systematic isolation of the network, proxy, application, and database tiers.
Step 1: Diagnose the Proxy and Network Layer
In most enterprise environments, Jira is not exposed directly to the internet or internal network. Instead, traffic routes through a reverse proxy. When a user requests a heavy operation—such as loading a board with thousands of issues or exporting a massive filter—Jira might take 60 to 120 seconds to process the request.
If your reverse proxy is configured with a strict 60-second timeout, it will sever the connection to the client and return a 504 Gateway Timeout, even if Tomcat is still happily crunching the data in the background.
To diagnose this, correlate the timestamps of the 504 errors in your proxy's access logs with Jira's atlassian-jira-security.log and catalina.out. If Jira eventually completes the request minutes after the proxy threw the error, the proxy timeout is the culprit.
Fixing NGINX Proxy Timeouts:
If using NGINX, you need to adjust the proxy_read_timeout and proxy_connect_timeout directives in your server block or location block for Jira.
location / {
proxy_pass http://jira_upstream;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
proxy_send_timeout 300s;
}
After updating, reload the configuration using nginx -s reload.
Step 2: Tomcat Application Server Tuning
If the proxy is not the issue, the bottleneck may lie within Apache Tomcat. The server.xml file (located in <JIRA_INSTALL>/conf/server.xml) defines how Tomcat handles incoming HTTP connections. Two primary configurations cause timeouts here: an exhausted thread pool or an insufficient connection timeout.
When multiple users hit Jira simultaneously, Tomcat assigns a thread from its pool to handle each request. If the maximum number of threads (maxThreads) is reached, incoming requests are placed in a queue (acceptCount). If the queue fills up, Tomcat outright refuses connections, leading to immediate timeouts.
Diagnosing and Fixing Tomcat Bottlenecks:
Check catalina.out for warnings indicating that the thread pool is exhausted. You can resolve this by increasing the maxThreads and adjusting the connectionTimeout (measured in milliseconds).
Open server.xml and locate the <Connector> element:
<Connector port="8080"
maxThreads="200"
minSpareThreads="25"
connectionTimeout="20000"
enableLookups="false"
maxHttpHeaderSize="8192"
protocol="HTTP/1.1"
useBodyEncodingForURI="true"
redirectPort="8443"
acceptCount="100"
disableUploadTimeout="true"/>
Increase maxThreads incrementally (e.g., to 300 or 400), but be warned: adding more threads consumes more RAM and CPU. If connectionTimeout is set to 20000 (20 seconds), consider increasing it to 60000 (60 seconds) for environments with heavy API usage.
Step 3: JVM Garbage Collection and Heap Exhaustion
Jira operates within a Java Virtual Machine (JVM). If the JVM is not allocated enough heap memory (-Xmx), it will spend a disproportionate amount of time performing Garbage Collection (GC) to free up space. Major GC events are 'Stop-The-World' operations—meaning all application threads, including those serving user requests, are completely paused.
If a GC pause lasts for 30 seconds, any request waiting for a response will likely time out at the proxy or client level. Furthermore, if the heap is completely exhausted, Jira will throw a java.lang.OutOfMemoryError: Java heap space in catalina.out and become entirely unresponsive.
Tuning the JVM:
Locate your setenv.sh (Linux) or setenv.bat (Windows) file in the <JIRA_INSTALL>/bin/ directory. Monitor your memory usage using tools like Datadog, Prometheus/Grafana, or natively using jstat.
If heap exhaustion is the root cause, increase the maximum heap size:
# Inside setenv.sh
JVM_MINIMUM_MEMORY="4096m"
JVM_MAXIMUM_MEMORY="8192m"
Ensure that the physical server has sufficient RAM to accommodate the OS, the new JVM heap, and other running services.
Step 4: Database Connection Pool Exhaustion
Every action in Jira requires database interaction. Tomcat threads borrow database connections from a pool (managed by HikariCP or Apache Tomcat JDBC). If complex queries (like deeply nested JQL searches or poorly optimized third-party app queries) tie up all available connections, new Tomcat worker threads will block while waiting for a database connection to become available.
Once the wait time exceeds the configured threshold, the thread drops the request, resulting in a timeout.
Fixing the Database Pool:
Check the <JIRA_HOME>/dbconfig.xml file. The <pool-max-size> setting dictates how many concurrent connections Jira can open to the database.
<jdbc-datasource>
...
<pool-max-size>100</pool-max-size>
<pool-min-size>20</pool-min-size>
<pool-max-wait>30000</pool-max-wait>
...
</jdbc-datasource>
If you have increased Tomcat's maxThreads, you must proportionately increase <pool-max-size>. A general rule of thumb is that the database connection pool should be at least equal to, or slightly larger than, the Tomcat maxThreads value, although this depends on your specific workload. Always ensure your database server (e.g., PostgreSQL max_connections) is configured to accept the increased connection load from Jira.
Frequently Asked Questions
#!/bin/bash
# Diagnostic script for identifying Jira Connection Timeout root causes
echo "=== Jira Timeout Diagnostic Script ==="
# 1. Check if Jira port is actively listening and responsive locally
JIRA_PORT=8080
echo "[1] Checking local port $JIRA_PORT connectivity..."
curl -I -s --max-time 5 http://localhost:$JIRA_PORT/status > /dev/null
if [ $? -eq 0 ]; then
echo "Success: Tomcat is responding locally."
else
echo "Warning: Tomcat is not responding locally within 5 seconds."
fi
# 2. Check NGINX access logs for 504 Gateway Timeouts in the last 1000 lines
NGINX_LOG="/var/log/nginx/access.log"
if [ -f "$NGINX_LOG" ]; then
echo "[2] Checking NGINX for 504 Gateway Timeouts..."
TIMEOUT_COUNT=$(tail -n 1000 $NGINX_LOG | awk '{print $9}' | grep -c "504")
echo "Found $TIMEOUT_COUNT occurrences of 504 timeouts recently."
fi
# 3. Analyze Tomcat logs for Thread Pool Exhaustion or OutOfMemory
CATALINA_OUT="/opt/atlassian/jira/logs/catalina.out"
if [ -f "$CATALINA_OUT" ]; then
echo "[3] Checking catalina.out for critical errors..."
grep -i "java.lang.OutOfMemoryError" $CATALINA_OUT | tail -n 5
grep -i "Maximum number of threads" $CATALINA_OUT | tail -n 5
fi
# 4. Check JVM Garbage Collection statistics (requires jstat)
JIRA_PID=$(pgrep -u jira java)
if [ ! -z "$JIRA_PID" ]; then
echo "[4] Checking JVM GC Stats for PID $JIRA_PID..."
echo "Columns: S0 S1 E O M CCS YGC YGCT FGC FGCT GCT"
jstat -gcutil $JIRA_PID 1000 3
else
echo "Warning: Could not find Jira Java process."
fi
echo "=== Diagnostics Complete ==="Error Medic Editorial
The Error Medic Editorial team comprises Senior SREs and Atlassian Certified Experts dedicated to providing actionable troubleshooting guides for enterprise software infrastructure.
Sources
- https://confluence.atlassian.com/jirakb/troubleshooting-performance-issues-in-jira-server-111562.html
- https://confluence.atlassian.com/jirakb/how-to-fix-out-of-memory-errors-by-increasing-available-memory-190407142.html
- https://confluence.atlassian.com/jirakb/tuning-database-connections-105054.html
- https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/#passing-a-request-to-a-proxied-server