Skip to main content

Jobs Will Not Run

Pending, failing, slow, or vanishing jobs — and what to do about each.


A Job Stays Pending

Pending is normal — Slurm has not found matching resources yet. The reason is in squeue:

squeue -j <jobid> -o "%.18i %.9P %.30j %.8T %.10M %.30R"

The last column names the cause.

ReasonMeaningFix
ResourcesNot enough free nodes or GPUs right nowWait, ask for less, or scale up
PriorityHigher-priority jobs are aheadWait, or use a partition with a higher priority tier
PartitionNodeLimitThe job wants more nodes than the partition holdsFix --nodes, or add nodes to the partition
PartitionTimeLimit--time exceeds the partition's Max timeLower --time, or raise the partition's limit
ReqNodeNotAvailA requested node is down, drained or unknownCheck the Nodes tab and sinfo -N -o "%N %t %E"
PartitionDown / PartitionInactiveThe partition is not accepting jobsSet its State back to UP
AssocMaxJobsLimit, QOSMax…An account or QoS limit is reachedWait for your other jobs to finish
InvalidQOS / InvalidAccountThe job names something that does not existFix the job script. TIR does not create QoS entries
DependencyA job it depends on has not finishedCheck the dependency's state
BeginTimeIt is scheduled to start laterExpected

When the request cannot ever be satisfied

The most common trap: asking for more than any single node has.

# What does a node actually offer?
sinfo -N -o "%N %c %m %G" # CPUs, memory, GRES
scontrol show node slinky-0 # full detail
# What did the job ask for?
scontrol show job <jobid> | grep -E 'NumNodes|NumCPUs|TRES|MinMemory'
--gres=gpu:16 on 8-GPU nodes pends forever

GRES is per node, not per job. For 16 GPUs across two 8-GPU nodes:

#SBATCH --nodes=2
#SBATCH --gpus-per-node=8

Slurm does not report this as an error — it simply waits, indefinitely, for a node that will never exist.

A partition that lost its nodes stops existing

If a scale-down removed every node a partition named, the partition is no longer written to slurm.conf and shows as not live in the partition table. Jobs targeting it never schedule. Repoint it at nodes that exist.

Capacity looks free but nothing schedules

sinfo -N -o "%N %t %E"

Any node in drain shows its reason in %E. A reason you recognise from your own Worker Prolog means the prolog is failing and draining nodes one job at a time. Resume with:

scontrol update nodename=slinky-3 state=resume

A Job Fails Immediately

Read the exit code and your own log first:

sacct -j <jobid> --format=JobID,JobName,State,ExitCode,Elapsed,NodeList,Reason
cat /pfs/logs/<jobname>-<jobid>.err
SymptomCauseFix
ExitCode 1:0 with a Python tracebackYour codeRead the traceback in the .err file
ExitCode 127Command not foundThe binary is not in the environment. In a container job, check the image has it; #!/bin/bash in a minimal image also gives 127 — use sh
ExitCode 2 from the shellScript syntax, or a missing fileCheck paths, and that the script is executable
No output file at allThe --output directory does not exist, or is not writablemkdir -p /pfs/logs, and confirm the path is on a mounted volume
Permission denied writing outputOutput is pointed at a dataset mountDatasets are read-only. Use PFS or SFS
slurmstepd: error: execve(): No such file or directoryThe job's command does not exist on the nodeWrong path, or you expected something the node does not have — run it in a container
JOB <id> CANCELLED ... DUE TO TIME LIMITIt hit --timeRaise --time, within the partition's Max time
Job killed... out of memory (host RAM)Host memory, not GPURaise --mem, or reduce dataloader workers
NODE_FAILThe node died mid-jobCheck the Nodes tab for XID errors
Invalid generic resource (gres) specificationThis cluster's Slurm does not sub-allocate GPUsRequest whole nodes with --nodes=N --exclusive instead of --gres=gpu:N. See below
--output outside a mounted volume loses the evidence

If the job's log went to a node-local path, the pod recreation that follows a failure takes it with it — and you are left debugging with nothing. Always point --output and --error at your PFS or SFS mount.

Reproduce interactively

Far faster than resubmitting a batch job:

srun --partition=all --nodes=1 --gres=gpu:1 --time=00:30:00 --pty bash

You are on a compute node with the same resources. Run your command by hand and watch it fail.


GPU Requests Are Rejected

srun: error: Unable to allocate resources: Invalid generic resource (gres) specification

The cluster's Slurm is not set up to allocate GPUs individually, so --gres=gpu:N and --gpus-per-node=N are not accepted. Confirm what the nodes advertise:

sinfo -N -o "%N %G"          # the GRES column
scontrol show node slinky-0 # look for Gres= and CfgTRES=

Work around it by taking whole nodes:

#SBATCH --nodes=1
#SBATCH --exclusive

Your job then has every GPU on the node, and nvidia-smi inside it shows all of them. For multi-node work, --nodes=N --exclusive plus --ntasks-per-node behaves as you would expect.

This is a cluster-level setting, not something you can change

It is not fixable from the Slurm Configuration dialog — the relevant directives are platform-managed. If your workload needs per-GPU allocation, raise a support request naming the cluster and its image version.


CUDA Out of Memory

The GPU ran out of memory. Host RAM OOM looks different — Slurm kills the job and says so.

FixHow
Reduce batch sizeThe first thing to try
Gradient accumulationKeeps the effective batch size while lowering peak memory
Mixed precisiontorch.autocast / bf16 roughly halves activation memory
Gradient checkpointingTrades compute for memory on deep models
Ask for a bigger GPUH200 has 141 GB against H100's 80 GB
Shard the modelFSDP, DeepSpeed ZeRO, or tensor parallelism across GPUs

Check what is actually being used while the job runs, on the Nodes tab or from a shell:

srun --jobid=<jobid> --overlap nvidia-smi
A previous job's leftovers can cause a false OOM

A crashed job can leave a process holding GPU memory. If a job OOMs at a batch size that worked yesterday, check for orphans:

srun --nodelist=slinky-0 nvidia-smi

A Worker Epilog that clears GPU state between jobs prevents this class of problem entirely.


A Job Is Slower Than Expected

Open Monitoring while it runs and read GPU Utilisation.

PatternDiagnosisFix
Utilisation high and steadyThe GPUs are the bottleneckThis is the healthy case. Optimise the model or add GPUs
Utilisation sawtoothingData pipeline bottleneck — GPUs waiting on I/OMore dataloader workers, prefetching, and make sure the dataset is on PFS not a slow path
Utilisation near zeroThe work is not on the GPUCheck the model and tensors are .to(device); check the job is not stuck in initialisation
One node lower than the othersA straggler rankPer-GPU drilldown on that node
Multi-node much slower than single-nodeCollectives falling back to TCPNCCL environment
Slow first step onlyContainer image import, or dataset cache warmingCache the image
Check utilisation on every new job script

A job that completes at 15% utilisation costs the same as one at 95% and takes six times as long. Two minutes with the Monitoring tab on a new script is the highest-return debugging you can do on a GPU cluster.

Prove the fabric before blaming your code

For multi-node runs, benchmark the collectives: Validate the fabric first.


A Job Disappeared

CauseHow to confirm
It completed and left the queuesacct -j <jobid> — it lives in accounting long after squeue forgets
Someone cancelled itsacct -j <jobid> shows CANCELLED and by whom
A restart ended itRestart All Workers, Restart Cluster and scale-down all end running jobs
The node failedsacct shows NODE_FAIL. Check the Nodes tab
sacct -u $USER -S today --format=JobID,JobName,State,ExitCode,Elapsed,End
Keep finished jobs in the Jobs tab longer

By default they leave squeue quickly and vanish from the tab. Raise MinJobAge in extra slurm.conf — for example MinJobAge=300.

On a shared cluster, scancel -u root cancels everything

If everyone logs in as root, one person clearing "their" jobs clears the whole cluster's. This is the strongest practical argument for Login User Management.


Make Jobs Survivable

PracticeWhy
Checkpoint to shared storage regularlyA node failure, preemption or restart ends the job. Progress is only as good as the last checkpoint
Make your script resume from the latest checkpointThen a restart costs minutes, not days
Always set --timeAn unbounded hung job holds GPUs indefinitely
Write --output and --error to PFS or SFSOtherwise the evidence dies with the pod
Use %x-%j in log filenamesRuns stop overwriting each other
Set partition Max timeA cluster-wide safety net against hung jobs

Last updated on September 10, 2026.