Null Pointer, Connection Refused, Timeout: Three Mnemonics to Slash Production Debugging Time
This guide provides step-by-step troubleshooting mnemonics for the three most common production errors—NullPointerException, Connection Refused, and Timeout—with concrete commands, log analysis techniques, and configuration checks to quickly isolate root causes.
One、Null Pointer Exception (NullPointerException)
1. Error Scene
Core signature: throws java.lang.NullPointerException with line numbers.
java.lang.NullPointerException: null
at com.xxx.biz.UserService.getUserInfo(UserService.java:47)
at com.xxx.controller.UserController.query(UserController.java:22)2. One-Minute Localization Method
Don't immediately blame developers. The most hidden cause: code queries DB or cache, gets null, then calls a method on that null object.
Step 1: Enable SQL logging to see if data was found
# In config file
logging.level.com.xxx.mapper: INFOReproduce the error and watch logs:
2025-05-22 14:23:15.678 INFO com.xxx.mapper.UserMapper.selectById - ==> Preparing: SELECT * FROM user WHERE id = ?
2025-05-22 14:23:15.679 INFO com.xxx.mapper.UserMapper.selectById - ==> Parameters: 12345 (Long)
2025-05-22 14:23:15.680 INFO com.xxx.mapper.UserMapper.selectById - <== Total: 0
2025-05-22 14:23:15.681 ERROR com.xxx.biz.UserService - Business processing exception
java.lang.NullPointerException: null
at com.xxx.biz.UserService.getUserInfo(UserService.java:47)
at com.xxx.controller.UserController.query(UserController.java:22)Key point: Total: 0 means SQL returned no rows, immediately followed by NPE.
Copy that SQL to a DB client and run manually to confirm missing data.
Step 2: Check for missing associated data
Many NPEs happen in joins: main table has record, but child table (e.g., user extension, org info) is empty. Code does user.getExtInfo().getPhone() but getExtInfo() returns null.
Troubleshooting: from the error line number, trace which object's attribute was called, then query the associated table for that business ID.
Step 3: Check if frontend omitted parameters
If error is at interface entry like request.getParam().getId(), frontend may have missed a field. Use F12 Network or nginx access logs.
3. Troubleshooting Guide
Enable SQL logging : logging.level.com.xxx.mapper: INFO → Find last SQL before error
Run SQL manually : Copy to DB client → Total: 0 → no data
Check associated tables : Query child table by business ID → No record → association missing
Inspect request params : F12 Network or nginx logs → Missing field → frontend issue
Check cache : redis-cli GET key → No key or expired
One-liner: For NPE, check SQL logs first—80% of the time the database is missing data. Don't rush to blame; verify your own data first.
Why Emphasize This?
In the last six months I've taught NPE troubleshooting over ten times. This field runs on experience; not knowing is normal, but refusing to learn is scary.
Most production NPEs aren't bad code—they're caused by implementation or ops manually inserting data halfway .
Example: Dev logic expects "user registration auto-creates extension record", but in test env you inserted into user table only, forgetting extension table. Then user.getExtInfo().getPhone() blows up.
You screenshot the dev saying "your code has NPE"; dev checks DB—extension table empty. Whose fault?
Lao Tang's experience:
80% of NPEs: database missing required data (not inserted, partial insert, missing associations).
20%: frontend missing params or code missing null checks.
So when NPE hits, don't restart, don't argue. Enable SQL logs, check Total==0, check associated tables. Lay out evidence:
If you missed inserting data → insert it, service recovers.
If dev forgot null check → bring evidence to dev for fix.
Remember: self-check data first, then approach dev. That's the baseline professionalism for an implementation engineer.
Two、Connection Refused (Connection refused)
1. Error Scene
Core signature: connecting to target service (Redis/MySQL/third-party API) fails with connection refused.
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at redis.clients.jedis.JedisFactory.makeObject(JedisFactory.java:...)Another common form:
Caused by: java.net.ConnectException: Connection refused: no further information
at org.springframework.data.redis.connection.RedisConnectionUtils.getConnection(...)2. One-Minute Localization Method
Don't scream "network down" on seeing "Connection refused". Test yourself first.
Step 1: Identify the target from stack trace redis.clients.jedis → Redis mysql.jdbc → MySQL org.springframework.web.client → external HTTP API rabbitmq, kafka → message queue
Step 2: Extract IP and port
Logs often include target address like 192.168.1.100:6379. If not, check config files.
Step 3: Manual connectivity test
On the application server, run:
telnet 192.168.1.100 6379
# or:
nc -vz 192.168.1.100 6379Step 4: Interpret results
Cannot connect → Target service down / firewall blocking → Ops or target service owner
Connects but app errors → Config file has wrong IP/port → Implementation or dev (wrong config)
Intermittent connect/timeout → Network instability or pool exhaustion → Network team or dev (pool config)
3. Troubleshooting Commands
Scenario 1: Target service not running
# Check process
ps -ef | grep redis
# Check status
systemctl status redis
# Start service (after confirming env)
systemctl start redisScenario 2: Firewall blocking
# View rules
iptables -L -n | grep 6379
# Temporarily allow (test env only; prod follows process)
iptables -I INPUT -p tcp --dport 6379 -j ACCEPTScenario 3: Config typo
Open config, verify IP and port:
redis:
host: 192.168.1.100 # confirm this machine
port: 6379 # confirm this portCommon low-level mistakes:
Extra whitespace
Using localhost but app container and Redis are on different hosts
Copy-paste forgot to change port
4. Why Force Manual Telnet?
Too many people see "Connection refused", screenshot, shout "network down", only to find later:
Config port typed as 6380 instead of 6379 (fat finger)
IP points to another environment (env config mixed up)
Service simply not started, nobody checked process
Implementation experience:
80% of connection refusals: wrong config or service not started , not real network failure.
15% firewall, only 5% genuine network faults.
So telnet first, conclude later . If telnet fails, escalate to network/ops; if telnet succeeds, check config and environment.
5. Troubleshooting Guide
Identify connection target : Read error stack → Redis/MySQL/HTTP/other
Find IP+port : Check config file → Record them
Manual telnet : telnet IP port → Success/fail
Check service process : ps -ef | grep service_name → Running?
Check firewall : iptables -L -n | grep port → Blocking rules?
Verify config : Open yml/properties → IP, port, env correct?
One-liner: Connection refused → telnet first. Success? check config. Fail? check service and firewall. Don't scream "network down"—80% of the time it's your own config typo or the service isn't running.
Three、Timeout Exceptions (Timeout / Read timeout / Connection timeout)
1. Error Scene
Three common timeout errors covering Redis, DB, external API calls:
# Redis read timeout
redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
# Redis connection timeout
org.springframework.dao.DataAccessResourceFailureException:
Unable to connect to Redis; nested exception is io.lettuce.core.RedisConnectionException:
Unable to connect to localhost/<unresolved>:6379
# External HTTP connection timeout
java.net.SocketTimeoutException: connect timed out2. One-Minute Localization Method
Many see "timeout" and yell "slow!", only to discover later it was a misconfigured parameter. Pause, follow these two steps.
Step 1: Distinguish timeout type (core of cores)
Lao Tang translates the jargon in error messages:
connect timed out → Connection timeout → Network unreachable, firewall blocking, target service down
Read timed out → Read timeout → Connection established, but peer processing too slow, exceeding wait time
Remember: can't connect = network/service issue; connected but slow = performance issue.
Step 2: Targeted troubleshooting by type
Case A: Connection timeout (connect timeout)
Follow "Connection Refused" section: telnet target IP:port to verify network and service.
If telnet fails → service down, firewall, network.
If telnet succeeds → check config: is connection timeout set too short (e.g., 1 second)?
Case B: Read timeout (read timeout)
First confirm if peer is genuinely slow: manually call API, check DB slow query logs.
Then check if your timeout config is too conservative (e.g., business normally needs 3s, you set 2s).
Use code instrumentation or packet capture to see where time is spent: network transfer? DB SQL? Third-party API?
3. Troubleshooting Guide
Scenario 1: Connection Timeout (connect timeout)
Per "Connection Refused" chapter: telnet target IP:port, confirm network and service normal.
If telnet works but app reports connect timeout, check if timeout config is too short:
# application-prod.yml or env config
spring:
redis:
connect-timeout: 3000ms # connection timeout, recommend 3-5 secondsScenario 2: Read Timeout (read timeout)
Confirm actual business latency: manually trigger call, see how long it takes.
If latency is genuinely long but business-acceptable, relax timeout:
spring:
redis:
timeout: 10000ms # read timeout, adjust per business, recommend 5-10 secondsIf latency fluctuates wildly, need dev to investigate (slow SQL, GC, lock contention).
Scenario 3: HTTP API Call Timeout (RestTemplate)
If app times out calling external API, check RestTemplate config:
@Bean
public RestTemplate restTemplate() {
SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
factory.setConnectTimeout(5000); // connect timeout 5s
factory.setReadTimeout(10000); // read timeout 10s
return new RestTemplate(factory);
}Also configurable via properties:
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 10000Scenario 4: Database Query Timeout
If error points to MySQL, check for slow queries:
-- View currently running queries exceeding 5 seconds
SELECT * FROM information_schema.processlist WHERE time > 5;Found slow query? Copy SQL, ask DBA or dev to optimize (add index, rewrite SQL, pagination).
4. Why Insist on Distinguishing These Two Timeouts?
Too many people see timeout and blame "network slow", only to discover: connect timeout because config file had wrong IP (connecting to non-existent server). read timeout because peer API is genuinely slow , but your timeout setting is shorter than business reality.
Implementation experience:
70% of connection timeouts: config error or service not started , not real network issue.
60% of read timeouts: configured timeout shorter than actual business latency .
Under 20%: genuine network latency or hardware faults.
So when timeout hits, first read the log: is it connect or read ? Then act. Don't scream "network slow" and make network team investigate for hours, only to find your own config typo.
5. Troubleshooting Checklist
Distinguish timeout type : Check log keyword → connect or read
Telnet test (connect timeout) : telnet IP port → Success/fail
Check service process : ps -ef | grep service_name → Running?
Check timeout config : Open yml/properties → Values reasonable?
Manual API latency test (read timeout) : curl or Postman → Actual seconds
Check DB slow queries : SELECT * FROM information_schema.processlist WHERE time > 5; → Long-running SQL?
Check log timestamps : Business log before/after call → Where time is spent
One-liner: Timeout → first split connect vs read . Connection timeout: follow "Connection Refused" to check network/service. Read timeout: increase timeout config first; if still fails, have dev profile business performance. Don't yell "network slow"—do the split yourself first.
Final Summary
Three core mnemonics for production errors—memorize and avoid half the pits:
Null Pointer → Enable SQL logs, check Total==0, prioritize self-check data issues.
Connection Refused → Telnet connectivity first. Success? check config. Fail? check service and firewall.
Timeout → Distinguish connect vs read, treat accordingly, don't blindly blame network.
Experience shows most production incidents aren't technically hard—they're experience and habit problems.
Some people only screenshot and hand off, or blindly trial-and-error. Master this standard flow and you can pinpoint root cause in one minute, resolve in ten. You'll not only resolve incidents efficiently but also assign responsibility with solid evidence, widening the gap between your capability and others'.
Over the years I've seen many juniors. Some are excellent —truly learn from one example and grow steadily. Others are "xiu" —also "learn from one example" (I say one thing, they argue three), deaf to any advice.
Jokes aside: humble learning is basic professionalism. Obsessing over trivialities and re-asking basics wastes your own growth and disrespects others' time and experience. Let's encourage each other.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Engineer Tang's Implementation Study Notes
Old Tang | Pseudo-full-stack tech player: writes code without going bald, manages projects without going crazy, delivers without staying up late. No formal tutorials here, only a "slacking-off" practical manual that cures system pain points. Focuses on Shell, SQL, Java, and delivery, turning complexity into simplicity and making efficiency fun.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
