IBM i message

CPF9999: Function check

CPF9999 is a function check. It means a program received an escape message that nothing handled. The message just before CPF9999 in the job log is the real error, and CPF9999 only tells you it wasn't handled.

Other names for this code

Also written as CPF9999 function check, MSGID CPF9999, function check IBM i, MONMSG CPF9999, AS400 function check.

What it means

When a command or operation fails on IBM i, it sends an escape message to the program that called it. That program can handle the message, for example with MONMSG in CL or a MONITOR group in RPG. When nothing handles it, the system sends a second message, CPF9999, called a function check. The function check names the original message and the statement where it arrived, and processing of that program stops.

In ILE programs, an unhandled exception moves up the call stack, giving each caller a chance to handle it. When it reaches the control boundary, it is turned into a function check and handling starts again. If the function check isn't handled either, ILE treats the application as having ended with an unexpected error and sends CEE9901 to the caller of the control boundary.

What the user sees depends on the language and the job. An RPG program's default handler shows an inquiry message about the original error with reply options. A CL program's error typically leads to an inquiry message as well. In an interactive job it appears on the screen. In a batch job it goes to the system operator's message queue, and the job waits for a reply unless the job's inquiry reply setting answers it automatically.

Common causes

  • A command in a CL program failed and the program had no MONMSG for that message, for example CPF9801 from a missing object or CPF4131 from a level check.
  • An RPG or COBOL program hit an error, such as decimal data or an array index out of range, and had no error handling for it.
  • A program received an escape message that a called program sent on purpose, such as CPF9898 with the application's own error text.
  • A file, library or authority problem made an open or call fail, and the program assumed it would always work.

How to find the problem

  1. Open the job log with DSPJOBLOG, or for a batch job open its QPJOBLOG spooled file with WRKSPLF or WRKJOB. Press F10 to show detailed messages.
  2. Find CPF9999 and read the message just above it. That is the real error. Put the cursor on it and press F1 for the full explanation.
  3. Press F1 on CPF9999 itself, then F9. The help names the message that wasn't monitored, and the details show the program, the statement number and the instruction where it happened.
  4. If the job ended and left no job log, change the job's logging so it keeps one, for example CHGJOB LOG(4 00 *SECLVL) LOGCLPGM(*YES), or set it on the job description, and run it again.

How to fix it

  • Fix the real error that the previous message describes. CPF9999 goes away when the cause does.
  • Where the error is expected and safe, add handling for that specific message, for example MONMSG MSGID(CPF9801) EXEC(GOTO CREATE) after the command that sends it.
  • Use a program-level MONMSG for CPF0000 or CPF9999 only as a last-resort error handler that logs or resends the original message. At program level, EXEC can only run a GOTO, and a handler that swallows errors hides them.
  • Reply C (cancel) to the inquiry message unless you know the program and the effect of the other replies. D also cancels and takes a dump for the developers.

What it looks like

Object PAYMAST in library *LIBL not found.
Function check. CPF9801 unmonitored by PAYR001 at statement 2100, instruction X'0021'.

IBM documentation

IBM Display Message Descriptions (DSPMSGD). Use the documentation for your installed release.

This link opens the relevant IBM reference library or lookup instructions. Match the complete code and your installed product release; it is not a code-specific review.

Read the installed message description:

DSPMSGD MSGID(CPF9999) MSGF(QSYS/QCPFMSG)

Also inspect the full job log and second-level message text, including substitution values.

Report a correction to WND Software.

Questions

What does function check mean on IBM i?

It means a program received an error message that it didn't handle. The function check message, CPF9999, points back to that original error, which comes just before it in the job log.

Should I fix CPF9999 or the message before it?

The message before it. CPF9999 only says the error wasn't handled. Fixing the original error, or handling it where that is safe, removes both.

Is MONMSG CPF9999 a good idea?

As a final catch-all that records the original error and ends cleanly, yes. As a way to ignore errors and carry on, no, because the program then runs on with bad results.