Troubleshooting playbook

When a Hadoop cluster misbehaves, the error message usually names the layer that broke: the network, HDFS, YARN, the job or security. This lesson reproduces four real incidents on our lab, then turns every failure we met in this course into a playbook: a method, a layered checklist and a table from message to first command.

Module 12 · Multiple clusters and operations⏱ 30 minIntermediate4 incidents reproduced20+ real messages mappedRuns in your browser (Python)8 practice problems
1 The story

Four alerts, one morning

Kabir has just joined the platform team. On his first on-call morning four messages arrive within an hour: an analyst gets “Connection refused”, the ingestion job can't create a folder, a report fails with “No live nodes contain current block”, and a second report has been sitting in ACCEPTED for twenty minutes while the cluster is half empty. He wants to restart everything. Arjun Sir asks him to open the playbook instead.

Connection refused (namenode:9000) → network/config: wrong port Name node is in safe mode. → HDFS NameNode: read-only No live nodes contain current block → HDFS DataNodes: replica down Queue's AM resource limit exceeded → YARN queue: AM limit network / DNS HDFS YARN job / security Four real messages from our lab. Each one points to one layer, so each needs a different first command. myphatshala.in
Kabir

Shall I just restart the NameNode and the ResourceManager? That fixes most things, right?

Arjun Sir

A restart hides the evidence and sometimes makes things worse: a restarted NameNode spends minutes in safe mode. Read each message first. Every one of them names a layer: the network, HDFS, YARN, or the job itself. Find the layer, then run the one command that confirms it.

Riya

So the four alerts are four different problems?

Arjun Sir

Yes, and none of them needs a restart. Today we reproduce all four on our lab, then build a playbook from every real failure we met in this course, so that next time the message itself tells you where to look.

2 Definition

A troubleshooting playbook

Formal definition (write this in exams)

A troubleshooting playbook (or runbook) is a documented, repeatable procedure for diagnosing and resolving operational incidents in a system. For Hadoop it combines a method (establish the symptom, its scope and recent changes; gather evidence from logs and metrics; form and test a hypothesis; apply the smallest safe fix; verify; record the incident) with a layered checklist that follows the dependency order of the platform: network and name resolution, HDFS (NameNode state and safe mode, DataNodes, block health), YARN (ResourceManager, NodeManagers, queues and limits), the application (ApplicationMaster, task attempts, input data) and security (authentication and authorisation). Each known symptom is mapped to its likely causes and the first command that confirms or rules them out. Incidents are closed with a blameless postmortem that improves the playbook, monitoring and automation.

In simple words

A doctor doesn't operate on everyone who says “it hurts”. They ask where, since when, what changed, look at test results, and then treat. A playbook is that routine written down for Hadoop: read the message, find the layer, run one command to confirm, fix the smallest thing, and write down what you learned.

Words you'll meet in this lesson

Runbook / playbookWritten steps for diagnosing and fixing known problems.
SymptomWhat someone sees: an error message, a slow job, an alert.
ScopeHow far it spreads: one job, one user, one node, one queue, whole cluster.
Blast radiusWhat else your fix might affect (a restart touches everyone).
Root causeThe underlying reason, not the first error you saw.
MitigationA quick step that stops the pain before the root cause is fixed.
PostmortemA written review after an incident: timeline, cause, fixes, lessons.
BlamelessThe review asks what failed in the system, not who to punish.

From our lab (Hadoop 3.5.0, four incidents reproduced)

Wrong porthdfs dfs -ls hdfs://namenode:9000/ → Call From namenode/172.22.0.2 to namenode:9000 failed on connection exception: java.net.ConnectException: Connection refused (the NameNode listens on 8020)
Safe modeCannot create directory /incident_b. Name node is in safe mode. Reading menu.csv still worked.
Lost replicaA file written with dfs.replication=1 lived only on worker2; with that DataNode stopped, the read gave up after 16 s: No live nodes contain current block. DataNode started → read worked again.
Stuck jobSecond job in ACCEPTED: Queue's AM resource limit exceeded. AM limit 768 MB, AM used 512 MB, while cluster memory was only 50% used.

Troubleshooting at three levels

Pick your level. New to this? Start at Beginner and climb.

Beginner Read the message, find the layer

  • Every Hadoop error message contains a clue word. Connection refused, UnknownHost: network or address. safe mode, block, replica: HDFS. queue, container, ACCEPTED: YARN. Exception at YourClass.java:27: your job.
  • Ask three questions before touching anything: what exactly fails, who else is affected, and what changed recently.
  • Never “just restart”. Look first, then change one thing.

Intermediate The method, step by step

  • Symptom: copy the exact message and time. Scope: one job, one user, one node, one queue, everyone?
  • Changes: a deploy, a config edit, a new data source, a node added or removed. Most incidents follow a change.
  • Evidence: hdfs dfsadmin -report, fsck, yarn node -list -all, yarn application -status, yarn logs, JMX metrics.
  • Hypothesis and one test that proves or disproves it. Then the smallest safe fix, then verify with the same command that showed the problem.

Advanced Operating like a platform team

  • Turn every incident into a playbook entry and, where possible, an alert (Lesson 12.4) or an automated check.
  • Separate mitigation (get the report out) from root cause (why the queue was too small). Track the second as a ticket.
  • Write blameless postmortems with a timeline, the detection gap (our stale-DataNode alert came 296 s late), and concrete follow-ups.
  • Practise: game days and DR drills (Lesson 12.2) find gaps before real incidents do.

Exam tip: For “How do you troubleshoot a failed Hadoop job?”, give the method (symptom → scope → recent changes → logs and metrics → hypothesis → smallest fix → verify → postmortem), the layer order (network, HDFS, YARN, application, security) and two real examples with their first command, e.g. safe mode → hdfs dfsadmin -safemode get; stuck in ACCEPTED → yarn application -status.

3 Types and ways to use it

The layered checklist

Architecture at a glance

Start at the top with the exact message, then walk down the layers in dependency order. A layer can only work if the ones above it work. Each box lists the first commands to run there.

Symptom: exact message + time Scope (job · user · node · queue · cluster) + what changed? 1 · Network/DNS getent hostsport right?8020 · 8088 Connection refused 2 · HDFS dfsadmin -report-safemode getfsck /path safe modemissing blocks 3 · YARN yarn node -list -allapp -statusscheduler REST AM limit, queue 4 · Job yarn logsattempts (REST)counters exception +line number 5 · Security klistgetfaclNN audit log cannot authenticatePermission denied Smallest safe fix → verify with the same command → postmortem Walk left to right: a job can't run if YARN is broken, YARN can't read input if HDFS is broken. myphatshala.in

Key commands for each layer

LayerCommandWhat it tells you
Networkgetent hosts namenode, hdfs getconf -confKey fs.defaultFSWhich address a name resolves to; which NameNode URI the client really uses
DaemonsjpsWhich Java daemons are running on this machine
HDFShdfs dfsadmin -report, -safemode getLive/dead DataNodes, capacity, safe mode
HDFShdfs fsck /path -files -blocks -locationsMissing, corrupt, under-replicated blocks and where replicas are
YARNyarn node -list -allRUNNING, UNHEALTHY, LOST, DECOMMISSIONED NodeManagers
YARNyarn application -status <app>State, final status and the diagnostics line
YARNcurl …:8088/ws/v1/cluster/schedulerQueue usage, AM limit, user limits
Jobyarn logs -applicationId … -containerId …The exception and stack trace of a failed attempt
Metricscurl …:9870/jmxThe same numbers the monitoring system reads (Lesson 12.4)
Daemon logsNameNode, ResourceManager logs (docker logs in our lab, $HADOOP_LOG_DIR on servers)Why a daemon refused to start or stopped

Symptom → likely cause → first command (real failures from this course)

Message you seeLikely causeFirst commandLesson
Connection refused (namenode:9000)Wrong port, daemon down, or a name resolving to the wrong networkgetent hosts, jps12.6, 12.1
UnknownHostException: nn-canteenName not resolvable (or that NameNode is down)getent hosts nn-canteen7.2
Name node is in safe mode.Startup, too few blocks reported, or manual safe modehdfs dfsadmin -safemode get12.6, 5.6
No live nodes contain current blockAll replicas of a block on stopped/dead DataNodeshdfs fsck /path -files -blocks -locations12.6
Timed out waiting 20000ms for a quorumMajority of JournalNodes down: NameNode stopsjps on JournalNode hosts7.1
The DiskSpace quota … is exceeded … diskspace consumed = 384 MBSpace quota counts a whole block × replicationhdfs dfs -count -q -h /dir7.4
Many under-replicated blocks, none missingJob staging files asked for replication 10hdfs fsck / | grep -i "under rep"12.4
Stuck in ACCEPTED: Queue's AM resource limit exceeded.Queue's ApplicationMaster limit (10% by default)yarn application -status12.6
InvalidResourceRequestExceptionAsked for more than maximum allocationyarn node -list -showDetails11.2
RM won't start: Queue configuration missing child queue names for rootBroken capacity-scheduler.xmlResourceManager log11.4
Error: Java heap spaceTask heap too small for what it keeps in memoryyarn logs of the attempt11.4
Exit code 137Container killed (kill -9 or memory limit)attempt diagnostics (REST)8.6
NumberFormatException: For input string: "abc" at ItemRevenue.java:27Bad input recordyarn logs, then search the data11.5
Too many counters: 121 max=120Dynamic counter per keyattempt diagnostics9.4
Illegal partition for chai (4)Partitioner returned a wrong numberyarn logs9.2
NoSuchMethodException … <init>()Writable without a no-argument constructoryarn logs9.3
PipeMapRed.waitOutputThreads(): subprocess failed with code 1Streaming script crashed; real error in stderryarn logs -log_files stderr9.8
ClassNotFoundException: com.github.luben.zstd.RecyclingBufferPoolJar on the client but not on the task classpathcheck -libjars10.2
FileAlreadyExistsException / InvalidInputExceptionOutput exists / input path wronghdfs dfs -ls both paths8.6
Client cannot authenticate via:[TOKEN, KERBEROS]No Kerberos ticketklist12.5
KerberosAuthException … Unable to obtain password from userKeytab missing or not readable when the daemon startedklist -kt keytab12.5
DR copy “succeeded” but old content remainsPlain DistCp skips same-name, same-size filesrerun with -update12.2
Alert arrived minutes lateStale-DataNode count recomputed on the heartbeat check (296 s in our lab)check the metric's update interval12.4

Animated example: the 6 AM report that never came

A railway reservations report, traced 6 steps
Animated example nightly_bookings_report · queue: reports 06:05 · report missing No failure alert fired. Nothing FAILED. Priya, on call, starts with the symptom. Scope: one queue? the whole cluster? $ yarn application -listapp_…_0912 RUNNING (zone summary)app_…_0913 ACCEPTED since 01:00 06:07 · the report never started $ yarn application -status app_…_0913Queue's AM resource limit exceeded. 06:09 · the message names the layer: YARN queue cluster memory 50% used, so not "cluster full" $ curl …/ws/v1/cluster/schedulerreports: AM limit 4 GB, AM used 4 GBlong-running 'zone summary' AMs 06:14 · AM slots taken by a stuck job 06:16 · smallest safe fix kill the stuck zone summary (it can rerun), no config change, no restart the report's AM starts within seconds 06:48 · report delivered Postmortem: alert on "ACCEPTED > 15 min", raise maximum-am-resource-percent for 'reports', timeout for the zone job. Priya's path symptom → scope: one app → diagnostics → queue metrics → smallest fix → verify + postmortem myphatshala.in

Keep the playbook next to your monitoring: every alert from Lesson 12.4 should link to the playbook entry that says what to check first.

4 Step by step

Four incidents on our lab

Run with trouble_lab.sh on the Module 8 lab (in “Run it on your PC”). Each step creates one incident, shows the exact message, and undoes it.

  1. A. Connection refused

    hdfs dfs -ls hdfs://namenode:9000/
    Call From namenode/172.22.0.2 to namenode:9000 failed on connection exception: java.net.ConnectException: Connection refused
    The machine answered, but nothing listens on port 9000. “Refused” means the host exists and the port is wrong or the daemon is down; “UnknownHost” would mean the name itself is wrong. Check hdfs getconf -confKey fs.defaultFS (8020 here) and jps.
  2. B. Safe mode

    hdfs dfsadmin -safemode enter
    hdfs dfs -mkdir /incident_b
    hdfs dfs -cat /user/hadoop/data/menu.csv | head -1
    hdfs dfsadmin -safemode leave
    Safe mode is ON Cannot create directory /incident_b. Name node is in safe mode. chai,drink,15,A Safe mode is OFF
    Writes fail, reads work: HDFS is read-only. Before leaving safe mode by hand, find out why it's on (-safemode get, NameNode log): after a restart it waits for enough block reports, and forcing it off with missing DataNodes can expose missing blocks.
  3. C. The only replica is on a stopped DataNode

    hdfs dfs -D dfs.replication=1 -put -f menu.csv /incident_c.csv
    hdfs fsck /incident_c.csv -files -blocks -locations
    docker exec lab8-worker2-1 hdfs --daemon stop datanode
    hdfs dfs -cat /incident_c.csv
    DatanodeInfoWithStorage[172.22.0.6 the only replica is on worker2; stopping its DataNode No live nodes contain current block the read gave up after 16 s DataNode back: chai,drink,15,A
    fsck … -locations showed the one replica's address. With replication 1 there is no second copy, so the client tries, waits and gives up. Starting the DataNode made the block available again: no data was lost, only unavailable. With replication 3 this read would have succeeded.
  4. D. A job stuck in ACCEPTED on a half-empty cluster

    yarn application -list
    yarn application -status application_…_0019
    curl -s http://resourcemanager:8088/ws/v1/cluster/scheduler
    application_1792661456575_0018 RUNNING application_1792661456575_0019 ACCEPTED Diagnostics : … Application is added to the scheduler and is not yet activated. Queue's AM resource limit exceeded. queue default | AM limit 768 MB | AM used 512 MB
    yarn.scheduler.capacity.maximum-am-resource-percent is 0.1 by default: 10% of 6,144 MB ≈ 614 MB, which the scheduler rounds up to 768 MB. One 512 MB ApplicationMaster fits; a second would need 1,024 MB. The cluster had memory free, but the queue had no ApplicationMaster room.
  5. Write it down

    Title       Nightly report stuck in ACCEPTED (incident D)
    Impact      report 48 min late, 1 queue, no data loss
    Timeline    01:00 submitted · 06:05 noticed · 06:09 diagnosed · 06:16 mitigated
    Root cause  queue AM limit (10%) filled by a long-running job
    Detection   no alert for "ACCEPTED too long"  ← gap
    Actions     alert on ACCEPTED > 15 min · AM percent 0.1 → 0.3 for reports · job timeout
    Blameless: it records what the system allowed, not who submitted the long job. The detection gap and the actions are the most valuable lines.

Under pressure, change one thing at a time and verify with the command that showed the problem. Two changes at once and you won't know which fixed it, or which made it worse.

5 See it happen

From message to layer to fix

Six steps through the four real incidents and the method that solved each one.

Four incidents 6 steps
What you see hadoop@namenode : ~ $ hdfs dfs -ls hdfs://namenode:9000/Call From namenode/172.22.0.2 tonamenode:9000 failed on connectionexception: ... Connection refused $ hdfs dfs -mkdir /incident_bCannot create directory /incident_b.Name node is in safe mode.$ hdfs dfs -cat .../menu.csvchai,drink,15,A $ hdfs fsck /incident_c.csv -locations1 replica: 172.22.0.6 (worker2)$ hdfs dfs -cat /incident_c.csvNo live nodes contain current block(gave up after 16 s) $ yarn application -list..._0018 RUNNING..._0019 ACCEPTEDQueue's AM resource limit exceeded.AM limit 768 MB | AM used 512 MB $ hdfs dfsadmin -safemode leaveSafe mode is OFF$ hdfs --daemon start datanode (worker2)DataNode back: chai,drink,15,A postmortem.mdroot cause · detection gap ·actions · playbook entry added myphatshala.in
Behind the screen network / addresses NameNode DataNodes w1 w2 w3 YARN: queue default (AM limit 768 MB) job / data port 9000: nothing listening (NameNode is on 8020) SAFE MODEreads yes · writes nothe NameNode refuses changes to the namespace w2 ✕1 replicano other copy of the block anywhere AM used 512 · a 2nd AM needs 1,024 > 768memory free, but no ApplicationMaster room writable againw2 back ✓smallest fixes, verified with the same commands four layers, four first commands, one playbook myphatshala.in
6 Real-world use

Playbooks at work

02:00 alert→ runbook link

1. On-call in a payments company

Every alert links to a runbook entry: what it means, the first command, the safe mitigation, and whom to call. The on-call engineer follows it before improvising.

Alert→Runbook entry→Mitigate, then root cause
postmortem5 actions

2. Blameless postmortems at an e-commerce company

After a festive-sale incident, the team writes a timeline and actions without naming a culprit. The actions (an alert, a quota, a test) are tracked like features.

Incident→Timeline + causes→Tracked actions

3. Game days at a telecom operator

The platform team breaks things on purpose in staging (stop a DataNode, fill a queue, expire a ticket) and times how long the on-call team needs to diagnose each one with the playbook.

Planned failure→Diagnose with playbook→Fix the gaps
auto-checkfsck, queues

4. Automated health checks at a government data platform

Steps that are always the same (safe mode? missing blocks? lost NodeManagers? apps stuck in ACCEPTED?) run as a script every few minutes and post a summary, so humans start with the evidence.

Script→Same first commands→Summary in chat
ticketwith evidence

5. Support tickets in a university research cluster

Students must attach the application ID, the exact message and the output of yarn application -status. Most tickets are solved from that alone, without logging in.

Student ticket→App ID + message→Answer from the table

Simplified; organisations differ in tools and policies.

7 Run the code

A symptom matcher for real error messages

The first step of every incident is reading the message. This matcher holds a few playbook rules (a pattern, the layer, the likely cause and the first command) and applies them to real messages from our lab.

import re
RULES = [
    (r"Connection refused",              "network", "wrong port or daemon down",       "getent hosts; jps"),
    (r"UnknownHostException",            "network", "name not resolvable",             "getent hosts <name>"),
    (r"in safe mode",                    "HDFS",    "NameNode is read-only",           "hdfs dfsadmin -safemode get"),
    (r"No live nodes contain",           "HDFS",    "every replica's DataNode is down", "hdfs fsck <path> -locations"),
    (r"AM resource limit exceeded",      "YARN",    "queue's ApplicationMaster limit",  "yarn application -status"),
    (r"Java heap space",                 "job",     "task heap too small",             "yarn logs (attempt)"),
    (r"cannot authenticate via",         "security","no Kerberos ticket",              "klist"),
]

def diagnose(message):
    for pattern, layer, cause, first in RULES:
        if re.search(pattern, message, re.IGNORECASE):
            return layer, cause, first
    return "unknown", "not in the playbook yet", "read the full log; add a rule"

messages = [
    "Call From namenode/172.22.0.2 to namenode:9000 failed on connection exception: java.net.ConnectException: Connection refused",
    "Cannot create directory /incident_b. Name node is in safe mode.",
    "No live nodes contain current block",
    "Application is added to the scheduler and is not yet activated. Queue's AM resource limit exceeded.",
    "Illegal partition for chai (4)",
]
for m in messages:
    layer, cause, first = diagnose(m)
    print(f"{layer:8} | {cause:32} | {first}")
network | wrong port or daemon down | getent hosts; jps HDFS | NameNode is read-only | hdfs dfsadmin -safemode get HDFS | every replica's DataNode is down | hdfs fsck <path> -locations YARN | queue's ApplicationMaster limit | yarn application -status unknown | not in the playbook yet | read the full log; add a rule
  • (r"AM resource limit exceeded", "YARN", "queue's ApplicationMaster limit", "yarn application -status"),Each rule is one playbook row: a clue in the message, the layer, the likely cause and the command that confirms it.
  • return "unknown", "not in the playbook yet", "read the full log; add a rule"A message with no rule is a gap in the playbook. After the incident, add a rule.

Run it on your PC: four incidents on purpose

Run this on your PC in the mr-lab folder with the Module 8 lab running. It creates each incident, prints the exact message, and puts things back: it leaves safe mode, restarts the DataNode it stopped and kills the two sleep jobs. It takes about 3 minutes.

Four incidents and their messages

# trouble_lab.sh: four common incidents reproduced on the Module 8 lab, with the exact message each one gives.
# Run on your PC.
NN="docker exec lab8-namenode-1"
clean() { grep -vE "^\s+at |INFO|^$|WARN.*retry|Retrying" | cut -c1-170; }
echo "== A. 'Connection refused': wrong port in the URI (8020 is right, 9000 was the Hadoop 1/2 habit)"
$NN hdfs dfs -ls hdfs://namenode:9000/ 2>&1 | grep -m1 -oE "Call From .* failed on connection exception: java.net.ConnectException: Connection refused"
echo "== B. 'Name node is in safe mode': writes fail, reads still work"
$NN hdfs dfsadmin -safemode enter 2>/dev/null
$NN hdfs dfs -mkdir /incident_b 2>&1 | grep -m1 -oE "Cannot create directory /incident_b. Name node is in safe mode."
echo "   read still works: $($NN hdfs dfs -cat /user/hadoop/data/menu.csv 2>/dev/null | head -1)"
$NN hdfs dfsadmin -safemode leave 2>/dev/null
echo "== C. a file with ONE replica, and its DataNode goes down"
$NN bash -c 'hdfs dfs -D dfs.replication=1 -put -f /tmp/mr/menu.csv /incident_c.csv 2>/dev/null; hdfs fsck /incident_c.csv -files -blocks -locations 2>/dev/null | grep -oE "DatanodeInfoWithStorage\[[0-9.]+"'
ip=$($NN hdfs fsck /incident_c.csv -files -blocks -locations 2>/dev/null | grep -oE "DatanodeInfoWithStorage\[[0-9.]+" | grep -oE "[0-9.]+$" | head -1)
for w in worker1 worker2 worker3; do
  if docker exec lab8-$w-1 hostname -i | grep -q "$ip"; then victim=$w; fi
done
echo "   the only replica is on $victim; stopping its DataNode"
docker exec lab8-$victim-1 hdfs --daemon stop datanode
$NN bash -c 'start=$(date +%s); hdfs dfs -cat /incident_c.csv 2>&1 | grep -m2 -oE "Could not obtain block: [^ ]+|BlockMissingException|No live nodes contain current block"; echo "   the read gave up after $(( $(date +%s) - start )) s"'
docker exec lab8-$victim-1 hdfs --daemon start datanode; sleep 15
echo "   DataNode back: $($NN hdfs dfs -cat /incident_c.csv 2>/dev/null | head -1)"
$NN hdfs dfs -rm -skipTrash /incident_c.csv > /dev/null 2>&1
echo "== D. a job stuck in ACCEPTED"
T=/opt/hadoop/share/hadoop/mapreduce/hadoop-mapreduce-client-jobclient-3.5.0-tests.jar
for n in 1 2; do $NN bash -c "export HADOOP_CLASSPATH=$T; yarn org.apache.hadoop.mapreduce.SleepJob -libjars $T -m 30 -r 1 -mt 30000 -rt 1000 > /tmp/acc$n.log 2>&1" & sleep 3; done
sleep 25
docker exec lab8-resourcemanager-1 yarn application -list 2>/dev/null | grep -E "RUNNING|ACCEPTED" | awk -F'\t' '{print "  ", $1, $6}' | tr -s ' '
app=$(docker exec lab8-resourcemanager-1 yarn application -list -appStates ACCEPTED 2>/dev/null | grep -o "application_[0-9_]*" | head -1)
docker exec lab8-resourcemanager-1 yarn application -status $app 2>/dev/null | grep -A2 "Diagnostics" | sed 's/^\s*/   /' | cut -c1-200
echo "-- the queue's limit on ApplicationMasters:"
docker exec lab8-namenode-1 curl -s http://resourcemanager:8088/ws/v1/cluster/scheduler | python3 -c '
import sys, json
q = json.load(sys.stdin)["scheduler"]["schedulerInfo"]["queues"]["queue"][0]
r = q["resources"]["resourceUsagesByPartition"][0]
print("   queue", q["queueName"], "| AM limit", r["amLimit"]["memory"], "MB | AM used", r["amUsed"]["memory"], "MB | maxAMPercent", q.get("maxAMPercent", q.get("maximumAMResourcePercent")))' 2>&1 | head -2
for a in $(docker exec lab8-resourcemanager-1 yarn application -list 2>/dev/null | grep -o "application_[0-9_]*"); do docker exec lab8-resourcemanager-1 yarn application -kill $a > /dev/null 2>&1; done
wait

# Run on your PC, in the mr-lab folder:
#   bash trouble_lab.sh
== A. 'Connection refused': wrong port in the URI (8020 is right, 9000 was the Hadoop 1/2 habit) Call From namenode/172.22.0.2 to namenode:9000 failed on connection exception: java.net.ConnectException: Connection refused == B. 'Name node is in safe mode': writes fail, reads still work Safe mode is ON Cannot create directory /incident_b. Name node is in safe mode. read still works: chai,drink,15,A Safe mode is OFF == C. a file with ONE replica, and its DataNode goes down DatanodeInfoWithStorage[172.22.0.6 the only replica is on worker2; stopping its DataNode No live nodes contain current block No live nodes contain current block the read gave up after 16 s DataNode back: chai,drink,15,A == D. a job stuck in ACCEPTED Total number of applications (application-types: [], states: [SUBMITTED, ACCEPTED, RUNNING] and tags: []):2 application_1792661456575_0018 RUNNING application_1792661456575_0019 ACCEPTED Diagnostics : [Thu Oct 22 10:37:12 +0000 2026] Application is added to the scheduler and is not yet activated. Queue's AM resource limit exceeded. Details : AM Partition = <DEFAULT_PARTITION>; AM Unmanaged Application : false Application Node Label Expression : <Not set> -- the queue's limit on ApplicationMasters: queue default | AM limit 768 MB | AM used 512 MB | maxAMPercent None

Real output. The DataNode holding the single replica depends on placement (worker2 in our run). The diagnostics line is cut at 200 characters; the full line also prints the AM partition and resource numbers.

8 Line by line

Walking the layers in order

A checklist in dependency order: stop at the first layer that fails. Watch layer and ok.

Worked examples: real problems, solved and traced in memory

Four incidents from different industries, each diagnosed from its message.

Example 1BeginnerDiagnose · network

An analyst at a hospital network gets “UnknownHostException”

Problem statement

A notebook in the hospital analytics team fails with java.net.UnknownHostException: nn-records. Other users can read HDFS. What layer is it, and what is the first check?

Input
message + scope: one user
Expected output
same? False | fix the client config: hdfs://nn-records:8020 -> hdfs://nn-patients:8020

Approach

  1. UnknownHost: the name itself does not resolve (not “refused”).
  2. Scope is one user, so the cluster is fine; look at that client.
  3. Compare the client's fs.defaultFS with a working user's.

Solution: run it live

What happens in memory, step by step

Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.

Example 2IntermediateDiagnose · HDFS

A telecom ingest job fails at midnight: safe mode

Problem statement

After planned maintenance on a telecom operator's cluster, the CDR ingest fails with “Name node is in safe mode.” hdfs dfsadmin -report shows 38 of 40 DataNodes live and the NameNode reports 99.7% of blocks. The threshold is 99.9%. What do you do?

Input
38/40 live · 99.7% reported · threshold 99.9%
Expected output
150,000 blocks not reported yet; threshold needs 49,950,000

Approach

  1. Safe mode is waiting for block reports.
  2. Two DataNodes are missing: start them, don't force safe mode off.
  3. Check what forcing would mean: some blocks have no live replica yet.

Solution: run it live

What happens in memory, step by step

Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.

Example 3IntermediateDiagnose · YARN

An e-commerce team's jobs wait in ACCEPTED

Problem statement

During a sale, 6 small jobs in the analytics queue sit in ACCEPTED. The queue has 200 GB, maximum-am-resource-percent 0.1 and each ApplicationMaster uses 4 GB. 5 are running. Why do the rest wait, and what is a safe change?

Input
200 GB · AM 10% · 4 GB per AM
Expected output
AM budget 20 GB -> 5 AMs; with 0.3: 15 AMs

Approach

  1. AM budget = 10% of the queue.
  2. Count how many AMs fit.
  3. Raise the percent for many small jobs, or wait.

Solution: run it live

What happens in memory, step by step

Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.

Example 4AdvancedDiagnose · data

A bank's report fails with Java heap space only on month end

Problem statement

A bank's reconciliation job succeeds every day but fails on the last day of the month with Error: Java heap space in one reduce task. Daily data is 40 GB; month-end adds a 25× spike for one account type. What is the likely cause and the first command?

Input
one reducer · month end · 25× one key
Expected output
normal reducer 0.8 GB, hot reducer 10.8 GB

Approach

  1. Only one reduce task fails: think skew (Lesson 8.5).
  2. A reducer holding all values of one hot key in memory runs out of heap.
  3. First: the failed attempt's log and the reduce input records per task.

Solution: run it live

What happens in memory, step by step

Recorded from a real Python run: press Next to execute one line at a time. Watch variables change in each frame, and lists and dictionaries (numbered #1, #2 …) fill up as objects.

9 Quiz and revision

Check yourself

Quick revision

Lesson 12.6 in one screen

  • Method: symptom → scope → recent changes → evidence → hypothesis → smallest safe fix → verify → postmortem.
  • Layers in order: network/DNS → HDFS → YARN → job → security; stop at the first broken one.
  • Connection refused = host reached, port wrong or daemon down; UnknownHost = the name doesn't resolve.
  • Safe mode: reads work, writes fail; find why before forcing -safemode leave.
  • “No live nodes contain current block”: every replica's DataNode is down; fsck -locations.
  • ACCEPTED on an idle cluster: check yarn application -status diagnostics (AM limit, queue limits).
  • Job errors: yarn logs of the failed attempt gives the exception and line (Lesson 11.5).
  • Blameless postmortem: timeline, root cause, detection gap, tracked actions; add a playbook rule and an alert.

Interview and viva questions

How do you troubleshoot a Hadoop cluster problem?

Record the exact error and time, establish the scope (one job, user, node, queue or the whole cluster) and what changed recently. Then check the layers in order: network and name resolution, HDFS (NameNode state, safe mode, DataNodes, blocks with dfsadmin -report and fsck), YARN (yarn node -list -all, application status and queue limits), the job (yarn logs of the failed attempt) and security (klist, permissions). Apply the smallest safe fix, verify with the same command, and write a postmortem.

Why is my YARN application stuck in ACCEPTED?

The scheduler has accepted it but cannot start its ApplicationMaster. Common causes are the queue's AM resource limit (maximum-am-resource-percent, 10% by default), the queue or user limit being used up, no NodeManager with enough free memory, or node labels that no node matches. yarn application -status shows the diagnostics, e.g. “Queue's AM resource limit exceeded.”

What does “Name node is in safe mode” mean?

The NameNode is read-only: it serves reads but refuses changes to the namespace. It enters safe mode at startup until enough DataNodes have reported their blocks (99.9% by default), or when an administrator turns it on. Check with hdfs dfsadmin -safemode get and find out why before leaving it by hand.

What does “Could not obtain block” or “No live nodes contain current block” mean?

The client could not read any replica of a block, usually because the DataNodes holding all replicas are down or unreachable. Use hdfs fsck <path> -files -blocks -locations to see where the replicas are, bring those DataNodes back, and check that important data has replication 3.

What is a blameless postmortem?

A written review after an incident that records the timeline, impact, root cause, why detection was late and the follow-up actions, without blaming individuals. It assumes people acted reasonably with the information they had and focuses on changing the system so the incident can't repeat.

Practice problems

Diagnosis exercises using the real messages and numbers from our lab.

P1Easy

Name the layer

For each message, print the layer: network, HDFS, YARN or job.

Input
4 real messages
Expected output
network  <- Connection refused
HDFS     <- Name node is in safe mode.
YARN     <- Queue's AM resource limit exceeded.
job      <- Error: Java heap space
Show solution and explanation
msgs = {"Connection refused": "network", "Name node is in safe mode.": "HDFS",
        "Queue's AM resource limit exceeded.": "YARN", "Error: Java heap space": "job"}
for m, layer in msgs.items():
    print(f"{layer:8} <- {m}")
network <- Connection refused HDFS <- Name node is in safe mode. YARN <- Queue's AM resource limit exceeded. job <- Error: Java heap space

How it works: The clue word in each message names its layer.

P2Easy

How late was the alert?

The DataNode stopped at 10:21:12 and the stale alert appeared at 10:26:08 (Lesson 12.4). How many seconds is the detection gap?

Input
two times
Expected output
296 s
Show solution and explanation
from datetime import datetime
a, b = datetime.strptime("10:21:12", "%H:%M:%S"), datetime.strptime("10:26:08", "%H:%M:%S")
print((b - a).seconds, "s")
296 s

How it works: 296 s: the stale-node count is recomputed on the NameNode's heartbeat check.

P3Easy

AM budget

What is 10% of 6,144 MB, rounded up to a multiple of 256 MB?

Input
6,144 MB · 0.1 · 256
Expected output
768 MB
Show solution and explanation
import math
print(math.ceil(6144 * 0.1 / 256) * 256, "MB")
768 MB

How it works: 768 MB, the AM limit our scheduler reported.

P4Medium

Replicas left

Given each block's replica nodes and the stopped node, list blocks that become unreadable.

Input
3 blocks · worker2 stopped
Expected output
['blk_1']
Show solution and explanation
blocks = {"blk_1": ["worker2"], "blk_2": ["worker1", "worker2", "worker3"], "blk_3": ["worker2", "worker3"]}
down = {"worker2"}
print([b for b, nodes in blocks.items() if set(nodes) <= down])
['blk_1']

How it works: Only blk_1 (replication 1) is lost from view; the others still have a live replica.

P5Medium

Build a timeline

Turn incident notes into minutes since the first event, skipping lines without a time.

Input
incident notes
Expected output
+  0 min  report missing
+  4 min  AM limit found
+ 11 min  stuck job killed
+ 43 min  report delivered
Show solution and explanation
notes = ["06:05 report missing", "checked dashboards", "06:09 AM limit found", "06:16 stuck job killed", "06:48 report delivered"]
t0 = None
for n in notes:
    first = n.split()[0]
    if ":" not in first:
        continue
    h, m = map(int, first.split(":"))
    t0 = t0 if t0 is not None else h * 60 + m
    print(f"+{h * 60 + m - t0:3d} min  {n[6:]}")
+ 0 min report missing + 4 min AM limit found + 11 min stuck job killed + 43 min report delivered

How it works: Diagnosed in 4 minutes, mitigated in 11, delivered in 43: the timeline of a postmortem.

P6Medium

Is it the cluster or the job?

A job failed on 4 attempts on 4 different nodes with the same exception. Is the cause the nodes or the job/data?

Input
4 attempts, 4 nodes, 1 exception
Expected output
job or data
Show solution and explanation
attempts = [("worker1", "NumberFormatException"), ("worker2", "NumberFormatException"),
            ("worker3", "NumberFormatException"), ("worker1", "NumberFormatException")]
nodes = {n for n, _ in attempts}
errors = {e for _, e in attempts}
print("job or data" if len(errors) == 1 and len(nodes) > 1 else "look at the nodes")
job or data

How it works: The same error on different nodes points at the code or the data (Lesson 11.5), not at a machine.

P7Business problem

Cost of restarting first

A NameNode restart costs 12 minutes of safe mode during which 300 analysts can't write. Diagnosing first takes 5 minutes and needs no restart. Compare lost analyst-minutes.

Input
12 min × 300 vs 5 min × 1
Expected output
restart first: 3600 analyst-minutes lost; diagnose first: 5 engineer-minutes
Show solution and explanation
print("restart first:", 12 * 300, "analyst-minutes lost; diagnose first:", 5, "engineer-minutes")
restart first: 3600 analyst-minutes lost; diagnose first: 5 engineer-minutes

How it works: 3,600 analyst-minutes vs 5: “just restart” is expensive even when it works.

P8Advanced

A tiny rule engine with priorities

Some messages match several rules (a Java heap space inside a failed Streaming task). Return the most specific rule (longest pattern).

Input
rules + message
Expected output
subprocess failed -> streaming script crashed
Show solution and explanation
import re
rules = {"Java heap space": "task heap too small", "subprocess failed": "streaming script crashed", "failed": "something failed"}
msg = "PipeMapRed.waitOutputThreads(): subprocess failed with code 1"
hits = [p for p in rules if re.search(p, msg)]
best = max(hits, key=len)
print(best, "->", rules[best])
subprocess failed -> streaming script crashed

How it works: “subprocess failed” beats the generic “failed”: specific rules first, generic ones as a fallback.

Real-world scenario questions (asked in company interviews)

Troubleshooting questions test method more than memory. Interviewers want to hear how you think under pressure.

Method · basicsFresher

“A user says HDFS is down. What do you do?”

A classic open question.

The interviewer is checking: method before action.

Show a strong answer
  • Get the exact message and time; check the scope: can I and other users list HDFS?
  • Check the NameNode (jps, web UI, hdfs dfsadmin -report, -safemode get) and the DataNodes.
  • If only that user fails, look at their client config and network (Connection refused, UnknownHost); if everyone fails, it's the NameNode or safe mode.
YARN · queuesExperienced

Jobs stuck in ACCEPTED, cluster 40% used

The business is waiting for a report.

The interviewer is checking: queue limits, not “add nodes”.

Show a strong answer
  • yarn application -status diagnostics: e.g. “Queue's AM resource limit exceeded” or user limit reached.
  • Scheduler REST/UI for that queue: AM limit vs AM used, capacity vs used, user limits.
  • Mitigate (kill or move a stuck job), then fix: raise maximum-am-resource-percent for queues with many small jobs, add an alert for long ACCEPTED times.
HDFS · dataExperienced

fsck reports missing blocks after a rack power failure

One rack of 20 nodes went down; it's back now, but 30 blocks are still missing.

The interviewer is checking: calm recovery, not deleting data.

Show a strong answer
  • hdfs fsck / -list-corruptfileblocks to list the files; -locations shows where replicas should be.
  • Check that all DataNodes of the rack really came back (dfsadmin -report), with all their disks mounted; missing disks are a common cause.
  • Only for blocks that are truly gone: restore from DR/backup (Lesson 12.2) or re-ingest; never run fsck -delete first.
Operations · cultureLead

“The same incident happened three times this quarter”

A director asks why.

The interviewer is checking: postmortems that lead to change.

Show a strong answer
  • Each time it was mitigated but the root-cause action wasn't owned or finished: track postmortem actions like product work.
  • Add detection (an alert), prevention (a quota, a config check in CI) and a playbook rule, so the fourth time is short or impossible.
  • Keep reviews blameless so people report near-misses early.