apache/hadoop · error · IllegalArgumentException

job control has circular dependency

Error message

job control has circular dependency

What it means

Error "job control has circular dependency" thrown in apache/hadoop.

Source

Thrown at hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/lib/jobcontrol/JobControl.java:215

    if (this.runnerState == ThreadState.SUSPENDED) {
      this.runnerState = ThreadState.RUNNING;
    }
  }
	
  synchronized public boolean allFinished() {
    return jobsInProgress.isEmpty();
  }
	
  /**
   *  The main loop for the thread.
   *  The loop does the following:
   *  	Check the states of the running jobs
   *  	Update the states of waiting jobs
   *  	Submit the jobs in ready state
   */
  public void run() {
    if (isCircular(jobsInProgress)) {
      throw new IllegalArgumentException("job control has circular dependency");
    }
    try {
      this.runnerState = ThreadState.RUNNING;
      while (true) {
        while (this.runnerState == ThreadState.SUSPENDED) {
          try {
            Thread.sleep(5000);
          }
          catch (Exception e) {
            //TODO the thread was interrupted, do something!!!
          }
        }
        
        synchronized(this) {
          Iterator<ControlledJob> it = jobsInProgress.iterator();
          while(it.hasNext()) {
            ControlledJob j = it.next();
            LOG.debug("Checking state of job "+j);

View on GitHub (pinned to 2add963021)

Solutions

  1. Remove the circular dependency between the jobs: inspect the Job objects added to JobControl and break the cycle so every job's dependency graph is a DAG.
  2. Re-check calls to ControlledJob.addDependingJob() and ensure a job never (directly or transitively) depends on itself.

Example fix

JobControl control = new JobControl("group");
ControlledJob a = new ControlledJob(conf);
ControlledJob b = new ControlledJob(conf);
b.addDependingJob(a); // correct: a runs before b; do NOT also call a.addDependingJob(b)
control.addJob(a);
control.addJob(b);

When it happens

Trigger: Thrown by JobControl.addJobs() when the dependency graph built from ControlledJob dependencies contains a cycle, so no topological ordering exists and the jobs can never all become ready. Fix by removing the circular ControlledJob.addDependingJob() chain.

Common situations: A job is accidentally added as its own dependency; two jobs each list the other in addDependingJob(); programmatically generated job graphs that create a cycle.


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/e669610e94a5ca36. Report an issue: GitHub.