COBOL File Status

In COBOL, every file I/O operation can succeed, hit a normal condition (like end of file), or fail. The FILE STATUS clause lets you capture a two-character status code after each operation so your program can react correctly. This page explains how to declare and use file status, what the two bytes mean, and how to handle the most common codes for sequential and keyed files.

Explain Like I'm Five: What Is File Status?

When you ask the computer to read or write a file, it can say "done," "there is nothing more to read," or "something went wrong." File status is that answer in the form of two letters or digits. Your program looks at those two characters and decides: keep going, stop reading, or show an error. So file status is just the program's way of knowing what happened after each file operation.

Declaring FILE STATUS

You associate a file with a status data item in the SELECT statement using the FILE STATUS clause. The status item must be exactly two bytes—typically PIC X(2) or PIC XX. It can be in WORKING-STORAGE or in a place that is accessible when the file is used. The runtime sets this item after every OPEN, CLOSE, READ, WRITE, REWRITE, DELETE, and START for that file. You should check it after each I/O to drive your logic.

cobol
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
WORKING-STORAGE SECTION. 01 WS-INPUT-STATUS PIC X(2). 01 WS-OUTPUT-STATUS PIC X(2). FD INPUT-FILE. 01 INPUT-RECORD PIC X(80). FD OUTPUT-FILE. 01 OUTPUT-RECORD PIC X(80). PROCEDURE DIVISION. OPEN-FILES. OPEN INPUT INPUT-FILE IF WS-INPUT-STATUS NOT = '00' DISPLAY 'Open input failed: ' WS-INPUT-STATUS STOP RUN END-IF OPEN OUTPUT OUTPUT-FILE IF WS-OUTPUT-STATUS NOT = '00' DISPLAY 'Open output failed: ' WS-OUTPUT-STATUS STOP RUN END-IF.

In the SELECT (in ENVIRONMENT DIVISION), you would have something like SELECT INPUT-FILE ASSIGN TO ... FILE STATUS WS-INPUT-STATUS. The exact syntax depends on your compiler; the important part is that each file has its own status item and you check it after every I/O.

The Two-Byte Status Code

The file status is two characters. The first character is the category; the second adds detail. So you can test the first byte to decide the kind of condition (success, at end, invalid key, permanent error, etc.) and optionally the full two bytes for specific handling. For example, 00 is success, 10 is end-of-file, 23 is record not found (invalid key), 30 is permanent error.

First-byte categories (x = second byte)
First byteCategoryMeaningTypical action
0xSuccessOperation completed successfully. Second byte gives detail (00 = normal success).Continue processing.
1xAT ENDSequential read reached end of file or optional file not present.Exit read loop; handle EOF.
2xInvalid keyKeyed operation failed: duplicate key, record not found, or sequence error.Check key and logic; handle duplicate or missing record.
3xPermanent errorSerious I/O or system error (e.g. disk failure, file not found at OPEN).Do not retry same op; log and recover or abend.
4xLogic errorProgrammer or logic error (e.g. wrong OPEN mode, invalid request).Fix program logic.
9xImplementer / runtimeCOBOL runtime or implementer-defined error.Check documentation; possible bug or environment issue.

Comparing the full two-byte value (e.g. IF WS-STATUS = '10') is reliable. Comparing only the first byte (e.g. WS-STATUS(1:1) or a reference-modified substring) lets you handle all "invalid key" codes (2x) together if you do not need to distinguish 21, 22, 23, etc.

Common File Status Codes

Exact codes can vary by compiler and file type (sequential, VSAM, etc.). The following are widely used. Always check your compiler and runtime documentation for the full list and for your environment.

Common status codes (representative)
CodeMeaningWhen it occurs
00Success.Any I/O completed normally.
02Duplicate key (optional).WRITE or READ on keyed file; duplicate key detected; optional key clause may allow continuation.
04Invalid record length.Fixed-length record file: record size does not match.
05Optional file not present.OPEN on optional file; file did not exist (often treated like empty).
10End of file.Sequential READ when no next record exists.
21Sequence error.Sequential file: key out of order (e.g. ascending key violated).
23Record not found.READ by key, REWRITE, DELETE, or READ after START; no matching record.
30Permanent error.System-level I/O failure (e.g. disk error, file not found for required file).
35File not found at OPEN.Non-optional file was not present at OPEN (e.g. missing dataset).

Code 00 is the only "all good" for normal continuation. Code 10 is normal for sequential files when you have read all records. Codes 23 and 30 are common for keyed and error handling: 23 for "record not found" or invalid key, 30 for serious I/O failure. Codes 05 and 35 relate to optional vs required files at OPEN: 05 often means optional file not present (acceptable); 35 means a required file was missing (error).

Checking Status After Each Operation

After OPEN, check that the status is 00 (or 05 for optional input if you allow it). After each READ, check for 00 (success), 10 (end of file for sequential), or an error code (e.g. 23, 30). After WRITE, REWRITE, DELETE, or START, check for 00 or the appropriate invalid-key or error code. After CLOSE, you can check for 00 to confirm no error. Many programs use EVALUATE WS-STATUS or a series of IF/ELSE to branch on the status and then PERFORM different paragraphs (e.g. EOF-PARAGRAPH, INVALID-KEY-PARAGRAPH, ERROR-PARAGRAPH).

cobol
1
2
3
4
5
6
7
8
9
READ-INPUT. READ INPUT-FILE AT END SET WS-EOF TO TRUE NOT AT END PERFORM PROCESS-RECORD END-READ IF WS-INPUT-STATUS NOT = '00' AND WS-INPUT-STATUS NOT = '10' DISPLAY 'Read error: ' WS-INPUT-STATUS PERFORM ABEND-ROUTINE END-IF.

Using AT END and NOT AT END is one way to handle 10 vs 00. The FILE STATUS is still set, so you can also rely on it alone: IF WS-INPUT-STATUS = '10' perform end-of-file logic, else if '00' process the record, else handle error. For keyed files, INVALID KEY and NOT INVALID KEY (or FILE STATUS 2x) drive the logic when the key is missing or duplicate.

Sequential vs Keyed Files

For sequential files, the codes you will see most are 00 (success), 10 (end of file), and sometimes 21 (sequence error if keys are out of order). For keyed files (e.g. VSAM KSDS), 00, 10, 23 (record not found), and 30 are common; 02 can appear for duplicate keys if the file allows it and you use the optional duplicate-key clause. OPEN failures (e.g. 35 for required file not found, 30 for other permanent errors) apply to both. The FILE STATUS clause works the same; only the set of possible codes and their meanings differ by file type.

Step-by-Step: Adding FILE STATUS to a File

  1. In WORKING-STORAGE (or another appropriate section), define a two-byte field, e.g. 01 WS-FILE-STATUS PIC X(2).
  2. In the SELECT statement for the file, add FILE STATUS WS-FILE-STATUS (or your chosen name).
  3. After every OPEN, READ, WRITE, REWRITE, DELETE, START, and CLOSE for that file, check WS-FILE-STATUS.
  4. Branch on 00 for success, 10 for end-of-file (sequential read), 2x for invalid key, 3x/4x/9x for errors, and handle each case (e.g. PERFORM paragraphs or set flags).

Step-by-Step: Handling End-of-File and Errors in a Read Loop

  1. Open the file and check status; if not 00 (and not 05 for optional), abort or report error.
  2. In the read loop, READ the file and then check FILE STATUS. If 00, process the record. If 10, leave the loop (end of file). If any other value, treat as I/O error: log the status, maybe display the record key or position, and exit or abend.
  3. After the loop, close the file and optionally check status again. Continue with the rest of the program.

Best Practices

Test Your Knowledge

Test Your Knowledge

1. After a READ, you should check FILE STATUS to:

  • Speed up the program
  • Decide if the read succeeded, hit EOF, or had an error
  • Clear the buffer
  • Close the file

2. File status 10 means:

  • Success
  • End of file
  • Invalid key
  • Permanent error

3. The first byte of a two-byte file status indicates:

  • The file number
  • The category (success, AT END, invalid key, etc.)
  • The record length
  • The key length