S0C2 — privileged-operation exception
The program tried to run an instruction only the operating system may use — in application code, a sign that control went to the wrong place.
What happened
The step abends with system completion code 0C2. Like S0C4 and S0C1 it is a program check, but this one says the instruction was valid and simply not allowed for this program.
IEA995I SYMPTOM DUMP OUTPUT SYSTEM COMPLETION CODE=0C2 REASON CODE=00000002 PSW AT TIME OF ERROR 078D1000 9A4F2E18 ILC 4 INTC 02 ACTIVE LOAD MODULE ADDRESS=1A4F2C00 OFFSET=00000218 CEE3202S The system detected a privileged-operation exception (System Completion Code=0C2). IEF450I INVJOB02 STEP020 - ABEND=S0C2 U0000 REASON=00000002
What it means
The processor met a privileged instruction: one reserved for the operating system running in supervisor state. Ordinary programs run in problem state, so the hardware refuses and z/OS ends the step with 0C2. Interrupt code 02 in the PSW line confirms it.
Compiled COBOL or PL/I never generates privileged instructions. In application code, S0C2 therefore usually means the same thing as S0C1: control went somewhere that is not real code, and the bytes there happened to decode as a privileged instruction.
Typical causes
- A branch to a bad address: a corrupted return address, a CALL through an unresolved or zero entry point, or a jump into a data area.
- Storage overlaid by the program, for example a table subscript running past its end and writing over saved addresses.
- A wrong-level or badly link-edited load module in the STEPLIB concatenation.
- In Assembler, code that issues a privileged instruction without running authorized; the fix is a design change, not an authorization workaround.
Symptoms
The PSW points into storage that is not the program's instructions, or into a module the program should not be running. The CEEDUMP traceback often shows the last good program and the call it made. A program that is not found gives S806 instead, and a bad operand address gives S0C4.
Where to look
- JESMSGLG: the symptom dump, PSW, interrupt code and active load module and offset.
- CEEDUMP: the traceback and the breaking-event address, which show how control arrived.
- The compile listing, to check whether the offset is inside the program's code at all.
- Binder output for every module in the call chain, looking for unresolved references.
- JESJCL: which libraries were searched and which copy of each module was loaded.
How to diagnose
- Confirm interrupt code 02 and note the failing address and module offset.
- Check whether the offset falls inside the module's code in the listing; if not, control went astray.
- Use the traceback and breaking-event address to find the last branch or CALL taken.
- Compare the module levels loaded with what the release was meant to promote.
- If nothing changed, suspect a storage overlay; reproduce in test with SSRANGE switched on.
How to fix
Fix the cause: correct the overlay or the CALL interface, relink cleanly, or promote the matching level of every program in the chain. For Assembler that genuinely needs a system service, use the documented interface for it; never try to make an application run authorized to get past S0C2.
How to prevent
- Treat binder warnings about unresolved references as build failures.
- Promote calling and called programs together when an interface changes.
- Use SSRANGE in test to catch subscripts and reference modification running out of range.
- Keep test and production library concatenations consistent.
Production considerations
Interview question
What is an S0C2, and how is it different from S0C1 and S0C4?
Stuck on something else?
Ask the community or search the full course.