Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

A JCL procedure, commonly called a PROC, is a reusable set of z/OS Job Control Language statements—usually one or more EXEC steps and their DD statements. A job invokes it with EXEC PROC=procname, optionally supplying symbolic parameters or overriding selected statements.

Procedures reduce duplicated JCL, standardize recurring batch operations, and let teams maintain common compile, bind, copy, sort, or execution logic in one place. They can be defined directly in a job as in-stream procedures or stored as members of a PDS or PDSE as cataloged procedures.

Why use a JCL procedure?

Without a procedure, every job that performs the same operation must repeat the same JCL. A procedure encapsulates that workflow and exposes only the values that normally change, such as source datasets, output datasets, high-level qualifiers, or environment names.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

This provides four practical benefits:

  • Reuse: one definition can support many jobs.
  • Consistency: standard DD statements, utilities, and execution steps are less likely to be copied incorrectly.
  • Centralized maintenance: a shared change can be made in one procedure member.
  • Parameterization: callers can supply job-specific values without copying the implementation.

The trade-off is that the effective JCL is no longer visible entirely in the calling job. A shared procedure change can also affect many jobs, so procedures should be treated as documented interfaces rather than anonymous blocks of reusable text.

In-stream versus cataloged procedures

Characteristic In-stream procedure Cataloged procedure
Location Inside the submitted job Member of a PDS or PDSE procedure library
Ending Must be terminated with PEND The stored member ends with the member; an in-stream PEND is not required
Reuse Usually limited to the job containing it Designed for use by multiple jobs
Best use Testing, demonstrations, or tightly coupled job logic Production standards and shared workflows
Lookup Found in the current input stream Found through JCLLIB and installation-configured procedure libraries

IBM documents these distinctions in How procedures are used. An in-stream procedure must be defined before the EXEC statement that calls it. IBM also documents a maximum of 15 in-stream procedures in one job.

Basic PROC syntax

A procedure begins with a PROC statement, contains ordinary JCL steps, and—when coded in the job stream—ends with PEND:

//TESTPROC PROC INPUT=TEST.INPUT
//STEP1    EXEC PGM=MYPROG
//INPUT    DD DSN=&INPUT,DISP=SHR
//OUTPUT   DD SYSOUT=*
//         PEND

The procedure is called with an EXEC statement:

//CALL     EXEC PROC=TESTPROC

The shorter form is also commonly used:

//CALL     EXEC TESTPROC

Use the explicit PROC= form when clarity matters, especially in teaching material or jobs that mix program and procedure calls.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Symbolic parameters: defaults and caller values

A symbolic parameter is a substitution variable, normally written with an ampersand, such as &INPUT or &LOADLIB. Declare it on the procedure’s PROC statement and reference it in the procedure body.

//COPYPROC PROC IN=DEFAULT.INPUT,OUT=DEFAULT.OUTPUT
//COPY     EXEC PGM=IEBGENER
//SYSUT1   DD DSN=&IN,DISP=SHR
//SYSUT2   DD DSN=&OUT,DISP=(NEW,CATLG,DELETE)
//SYSPRINT DD SYSOUT=*
//SYSIN    DD DUMMY
//         PEND

A caller can replace the defaults for one invocation:

//COPY1    EXEC PROC=COPYPROC,IN=TEST.INPUT,OUT=TEST.OUTPUT

For this invocation, the effective dataset references are:

//SYSUT1   DD DSN=TEST.INPUT,DISP=SHR
//SYSUT2   DD DSN=TEST.OUTPUT,DISP=(NEW,CATLG,DELETE)

The calling value takes precedence over the default on the PROC statement. Use descriptive names such as &HLQ, &SRCLIB, &LOADLIB, and &ENV. Document which symbols are required and which have safe defaults.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Symbols are substituted into JCL syntax, so their values must not accidentally break dataset-name rules, quotation marks, commas, parentheses, or continuation rules. A caller can assign an empty value:

//CALL     EXEC PROC=MYPROC,LOC=

However, nullification is context-sensitive. An empty value may leave an incomplete dataset name or parameter list and produce invalid JCL; it is not automatically equivalent to deleting a statement.

Cataloged procedures and procedure libraries

A cataloged procedure is stored as a member of a PDS or PDSE. The library may be a private application library, an installation-defined library, or a system library such as SYS1.PROCLIB. The actual libraries and search order are installation-dependent; not every z/OS environment uses the same configuration.

A cataloged member might contain:

//MYPROC   PROC SRC=APP.SOURCE(PROG1),
//             OBJ=APP.OBJECT(PROG1)
//COMPILE  EXEC PGM=IGYCRCTL
//SYSIN    DD DSN=&SRC,DISP=SHR
//SYSLIN   DD DSN=&OBJ,DISP=SHR
//SYSPRINT DD SYSOUT=*

For a private procedure library, identify the library with JCLLIB ORDER= before calling the procedure:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
//JOB1     JOB (ACCT),'JCL TEST',CLASS=A,MSGCLASS=X
//         JCLLIB ORDER=(USER.PROCLIB)
//CALL     EXEC PROC=MYPROC

When multiple libraries contain a member with the same name, the order in JCLLIB ORDER= can determine which definition is selected. IBM describes procedure invocation and lookup in Using a procedure and explains procedure-library organization in Managing procedure libraries.

Do not confuse JCLLIB with JOBLIB or STEPLIB

JCLLIB locates JCL procedure members. It does not locate program load modules. JOBLIB and STEPLIB affect program-library searches for modules used by PGM=. In other words:

  • EXEC PROC=MYPROC asks z/OS to find a procedure.
  • EXEC PGM=MYPROG asks z/OS to find a program module.

These are separate lookup problems. See IBM’s explanation of how z/OS finds a program or procedure.

Overriding a procedure for one job

A caller can customize a procedure without editing the stored member. Overrides are qualified by the procedure step name and, for DD statements, the DD name.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
MVS JCL in Plain English
  • Used Book in Good Condition

Override a DD statement

If the procedure contains:

//STEP1    EXEC PGM=MYPROG
//INFILE   DD DSN=PROD.INPUT,DISP=SHR

The calling job can select a test dataset:

//CALL     EXEC PROC=MYPROC
//STEP1.INFILE DD DSN=TEST.INPUT,DISP=SHR

STEP1.INFILE identifies the DD statement named INFILE inside procedure step STEP1.

Override an EXEC parameter

Procedure-step execution parameters can be overridden with the procedure step name:

//CALL     EXEC PROC=MYPROC
//STEP1    EXEC.PARM='TEST'

The exact parameters that can be overridden depend on the statement and the JCL rules for that parameter. DD, EXEC, and OUTPUT overrides should not be treated as interchangeable syntax.

Add a DD statement

A caller can add a DD statement to a procedure step:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
//CALL       EXEC PROC=MYPROC
//STEP1.EXTRA DD DSN=APP.EXTRA,DISP=SHR

This is useful only when the underlying program recognizes the added DD name and the procedure’s structure permits it.

Override, add, and nullify are different

  • Override: supply a different value for an existing procedure statement.
  • Add: supply a new statement, such as an additional DD.
  • Nullify: deliberately blank a value where the resulting JCL remains valid.

An override is not necessarily a wholesale replacement of every attribute associated with a DD statement. In complex cases, inspect the resulting effective JCL and consult the applicable z/OS MVS JCL Reference. An override also cannot be assumed to repair every invalid statement in the procedure; some errors occur during JCL processing before a useful correction can be applied.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Complete in-stream example

This example defines a procedure in the job, supplies a default message, and calls it with a different value:

//JOB1     JOB (ACCT),'JCL TEST',CLASS=A,MSGCLASS=X
//HELLO    PROC MSG='HELLO FROM JCL'
//STEP1    EXEC PGM=IEBGENER
//SYSPRINT DD SYSOUT=*
//SYSIN    DD DUMMY
//SYSUT1   DD *
&MSG
/*
//SYSUT2   DD SYSOUT=*
//         PEND
//CALL     EXEC PROC=HELLO,MSG='HELLO FROM TEST JOB'

After symbolic substitution, the input data effectively contains:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
HELLO FROM TEST JOB

The procedure must appear before //CALL EXEC, and PEND must mark its end. Quoting, commas, parentheses, and JCL continuation rules still apply after substitution.

Moving the procedure to a library

  1. Copy the procedure definition into a member of a PDS or PDSE, for example USER.PROCLIB(HELLO).
  2. Make sure the library is available to the job and that the user has access.
  3. Add JCLLIB ORDER=(USER.PROCLIB) if it is a private library.
  4. Remove the in-stream definition and its PEND from the job.
  5. Call the member by name with EXEC PROC=HELLO.

Whether a library is searched by default, and which installation libraries are configured, depends on the site’s JES and z/OS setup.

Troubleshooting common failures

Symptom Likely cause What to check
IEFC001I PROCEDURE MYPROC WAS NOT FOUND Wrong member, missing library, missing or incorrectly ordered JCLLIB, access failure, or unexpected installation configuration Verify the spelling, library qualification, search order, and access
Statements after a PROC are treated unexpectedly Missing or misplaced PEND Check the boundaries of the in-stream procedure
Procedure call fails even though the member exists The in-stream definition was placed after the call, or another same-named member was selected first Move the definition before the call and inspect library order
A symbol remains unresolved Misspelled or undeclared symbol, unsupported context, or malformed continuation/quoting Compare the symbol on the PROC statement with every reference and inspect resolved JCL
The wrong dataset is used Unsafe default, wrong symbolic value, or a different procedure member selected Review the effective JCL, procedure defaults, and JCLLIB ORDER=
An override has no effect Incorrect procedure-step or DD qualification Use procstep.ddname for DD overrides and verify the target names
JCL still fails after an override The underlying syntax or semantic error is unrelated to the overridden value Review the expanded statements against the z/OS JCL Reference

Designing safer procedures

  • Use meaningful, stable symbol names and document every parameter.
  • Choose defaults that are safe for the most common environment; avoid defaults that could unexpectedly target production data.
  • Keep installation-specific dataset names parameterized when they vary between environments.
  • Keep the public parameter list small. Excessive overrides make a procedure difficult to understand and maintain.
  • Test a new procedure in-stream before cataloging it, then test the cataloged member through the same lookup path production jobs will use.
  • Use controlled naming and versioning for shared procedure members.
  • Review the impact of every cataloged-procedure change because many jobs may consume the member.
  • When troubleshooting, inspect the expanded or resolved JCL rather than only the symbolic source.

IBM-supplied compiler, binder, and utility procedures are product- and installation-dependent. Their names, parameters, and availability should be verified on the target system rather than assumed to exist everywhere.

Procedures compared with related JCL features

A procedure is not the only way to reuse JCL:

  • Repeated ordinary JCL: suitable for a genuinely one-off job when abstraction would make the flow harder to read.
  • INCLUDE groups: useful for inserting reusable JCL fragments, especially DD or parameter groups. An include is not the same as a callable multi-step procedure.
  • SET and system symbols: parameterize job JCL without necessarily creating a reusable procedure.
  • JOBLIB and STEPLIB: identify program load libraries, not procedure libraries.
  • Scheduler-generated JCL: may generate, modify, or invoke procedures. Confirm whether the submitted JCL matches the scheduler repository source.

Bottom line

Use an in-stream PROC while developing or demonstrating a job-specific workflow. Use a cataloged procedure when multiple jobs need the same steps, and expose changing values through documented symbolic parameters. Remember that JCLLIB finds procedures, JOBLIB/STEPLIB find program modules, and procedure overrides must be qualified carefully. When a job fails, check the selected library member and the resolved JCL—not just the procedure call.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.