A batch job should run LOADSTEP only when VALIDATE ends with RC 0 or 4. JCL IF THEN ELSE ENDIF expresses that rule directly: JES evaluates the condition after the earlier step finishes, runs the matching branch, and continues after the closing ENDIF.
JCL IF THEN ELSE ENDIF syntax
Code the construct after the JOB statement. The IF statement contains a relational expression followed by THEN. ELSE is optional, but every construct requires a matching ENDIF. The expression is evaluated at execution time from results produced before the IF statement.
//CHKRC IF (VALIDATE.RC LE 4) THEN
//LOADSTEP EXEC PGM=PRODLOAD
//INFILE DD DSN=APP.INPUT.VALID,DISP=SHR
// ELSE
//ERRSTEP EXEC PROC=ERRPROC
// ENDIF
When VALIDATE.RC is 0 through 4, LOADSTEP runs. A higher return code selects ERRSTEP. Replace the program, procedure, and DD names with those used by the application.
Test a specific step return code
Use stepname.RC when the decision belongs to one earlier job step. Return codes are numeric values from 0 through 4095. Step names remove doubt when several prior programs have produced different return codes.
//RUNRPT IF (SORTSTEP.RC EQ 0) THEN
//REPORT EXEC PGM=RPTGEN
//SYSOUT DD SYSOUT=*
// ENDIF
This example runs REPORT only after SORTSTEP returns exactly zero. If SORTSTEP did not execute, an expression that references SORTSTEP.RC evaluates as false. That behavior matters when an earlier IF, COND parameter, restart, or error prevented the step from starting.
Understand unqualified RC
When no step name is present, RC means the highest return code produced by prior steps that executed. A step that did not start, was cancelled, or ended abnormally does not contribute a return code to that value. At the beginning of job execution, RC is initially zero.
//CONTINUE IF (RC LE 4) THEN
//NEXTSTEP EXEC PGM=APPLYUPD
// ELSE
//STOPPATH EXEC PROC=ERRPROC
// ENDIF
Use comparison and logical operators
| Purpose | Alphabetic form | Symbol form | Example |
|---|---|---|---|
| Equal | EQ | = | STEP1.RC EQ 0 |
| Not equal | NE | ¬= | STEP1.RC NE 4 |
| Greater / greater or equal | GT / GE | > / >= | RC GT 8 |
| Less / less or equal | LT / LE | < / <= | STEP1.RC LE 4 |
| Logical AND | AND | & | A.RC EQ 0 AND B.RC EQ 0 |
| Logical OR | OR | | | RC EQ 8 OR RC EQ 12 |
| Negation | NOT | ¬ | NOT STEP1.ABEND |
NOT is evaluated first, comparisons second, and logical operators third. Operators at the same priority are processed in coded order. Parentheses make mixed AND and OR expressions easier to review and protect the intended grouping.
Combine RC conditions safely
//GOODRUN IF ((EXTRACT.RC LE 4) AND
// (SORTSTEP.RC EQ 0)) THEN
//LOAD EXEC PGM=LOADDB
// ELSE
//REJECT EXEC PROC=ERRPROC
// ENDIF
The continued expression breaks where a blank is valid. Continue it in columns 4 through 16 of the next JCL statement, and do not place a comment on a statement being continued. Comments can follow after the expression is complete.
For multiple accepted return codes, an OR expression is clearer than a broad range when intermediate values have different meanings:
//ACCEPT IF ((CHECK.RC EQ 0) OR
// (CHECK.RC EQ 4)) THEN
//PROCESS EXEC PGM=DAILYRUN
// ENDIF
Test ABEND and ABENDCC
ABEND tests whether an earlier job step ended abnormally. Qualify it with a step name when recovery belongs to one step. ABENDCC can test a system completion code such as S0C7 or a user completion code such as U0100.
//BADPACK IF (CALCSTEP.ABENDCC = S0C7) THEN
//C7PATH EXEC PROC=ERRPROC
// ENDIF
//ANYABND IF (ABEND) THEN
//ABNDPATH EXEC PROC=ERRPROC
// ENDIF
An IF test is not a universal recovery mechanism. IBM documents abnormal termination cases that prevent either branch from executing regardless of an ABEND test. Preserve the normal scheduler, restart, dump, and operations procedures for failures that stop job processing.
Use RUN when execution itself matters
The RUN keyword tests whether a named step started execution. It helps distinguish “the step did not run” from “the step ran and returned a value.” Its negative form tests that the step did not start.
//DIDRUN IF (EXTRACT.RUN) THEN
//AUDIT EXEC PGM=AUDITLOG
// ENDIF
//SKIPPED IF (NOT EXTRACT.RUN) THEN
//NOTICE EXEC PROC=NOTIFY
// ENDIF
Use a site procedure or program that actually exists; the names above show the control structure. The JCL RESTART guide explains how restart selection changes which earlier steps execute.
Reference a step inside a procedure
For a step within a called procedure, qualify the test with both the job-step name and procedure-step name. The form is jobstep.procstep.RC. This prevents a procedure's internal step name from being confused with a top-level step.
//BLDAPP EXEC PROC=BUILDPRC
//LINKOK IF (BLDAPP.LINK.RC LE 4) THEN
//RUNTEST EXEC PGM=APPTEST
// ELSE
//FAILBLD EXEC PROC=ERRPROC
// ENDIF
Confirm the expanded procedure in the job listing before relying on the qualifier. See the JCL procedure guide for cataloged and in-stream procedure structure.
Know what can appear in a branch
Either the THEN clause or the ELSE clause must contain at least one EXEC statement; otherwise the construct has no executable branch. EXEC and its associated DD statements can be conditional, as can nested IF constructs and several step-level output or dump DD statements.
Do not place JOB, JCLLIB, JOBLIB, job-level SYSCHK, or XMIT statements inside a conditional branch. PROC, PEND, INCLUDE, comments, delimiter statements, null statements, and JES statements can appear there, but JES processes them regardless of the IF result.
Nest IF constructs with restraint
z/OS JCL permits up to 15 levels of IF/THEN/ELSE/ENDIF nesting. Each IF requires its own ENDIF. Give meaningful names to complex IF statements and indent examples consistently so an operator can match each ELSE and ENDIF during an incident.
//OKCOPY IF (COPYSTEP.RC EQ 0) THEN
//HASDATA IF (CHECK.RC EQ 0) THEN
//LOAD EXEC PGM=LOADDB
// ELSE
//EMPTY EXEC PROC=NODATAP
// ENDIF
// ELSE
//COPYERR EXEC PROC=ERRPROC
// ENDIF
Shallow constructs are easier to restart and diagnose. If several branches repeat the same DD statements, consider a procedure with symbolic parameters rather than adding more nesting.
IF THEN ELSE versus COND
IF/THEN/ELSE/ENDIF executes the THEN branch when its expression is true. A COND parameter works as a bypass test: when its comparison is true, the associated step is skipped. That inverse reading is the source of many maintenance errors.
Use IF constructs for new multi-step branching where readability matters. Keep the separate JCL COND parameter guide for existing procedures and step-level bypass rules. The JCL EXEC guide covers where COND, PARM, REGION, and procedure calls belong, while the JCL tutorial provides the JOB, EXEC, and DD structure around these examples.
Common errors and checks
| Symptom | Likely cause | Check |
|---|---|---|
| THEN branch never runs | Referenced step did not execute | Check the job log, preceding conditions, and stepname.RUN. |
| Unexpected branch runs | Unqualified RC used the highest prior return code | Replace RC with the intended stepname.RC. |
| JCL conversion error | Missing THEN, ENDIF, parentheses, or valid continuation | Match each IF to one ENDIF and inspect statement columns. |
| Expression groups incorrectly | Mixed AND and OR without clear parentheses | Parenthesize each comparison and the intended Boolean groups. |
| ABEND recovery step does not run | The failure prevented continued job processing | Use the job log and site recovery procedure; not every abend permits IF evaluation. |
| Procedure-step test is false | Qualifier uses the wrong invocation or procedure step name | Check the expanded JCL and code jobstep.procstep.RC. |
Production checklist
- Name the exact earlier step when the condition belongs to one result.
- Use unqualified RC only for a deliberate highest-prior-return-code rule.
- Use RUN when a skipped step must be distinguished from a completed step.
- Use ABENDCC only for a specific documented recovery path.
- Parenthesize combined conditions and verify operator order.
- Match every IF with ENDIF and keep nesting far below the 15-level limit.
- Ensure at least one of the THEN or ELSE clauses contains an EXEC statement.
- Review expanded procedures, INCLUDE members, and restart behavior.
- Test RC 0, RC 4, a failing RC, a skipped step, and an abend path.
Official IBM references
- IBM: Using IF/THEN/ELSE/ENDIF
- IBM: RC, ABEND, ABENDCC, and RUN keywords
- IBM: Operator forms and priorities
- IBM: Relational-expression field and continuation
- IBM: THEN and ELSE clause rules
JCL IF THEN ELSE ENDIF FAQ
What does RC mean in a JCL IF statement?
RC is a return-code keyword. Without a step name, it represents the highest return code from prior steps that executed. With a qualifier such as STEP1.RC, it tests that specific step's return code.
What happens if a referenced JCL step did not run?
When an IF expression names a step that did not execute, the expression for that step evaluates as false. Use the RUN keyword when the distinction between not run and a completed return code matters.
Can JCL IF THEN ELSE statements be nested?
Yes. z/OS JCL supports up to 15 levels of IF/THEN/ELSE/ENDIF nesting. Keep nesting shallow so operators, step names, and matching ENDIF statements remain easy to verify.
Is JCL IF THEN ELSE better than the COND parameter?
IF/THEN/ELSE/ENDIF usually reads more directly because its true branch runs, while a true COND test bypasses a step. Existing procedures can still use COND, so choose one clear style and verify its exact execution rule.
When a conditional job takes the wrong path, check whether the named step actually ran before changing the comparison; a valid return-code test cannot succeed for a step that never started.