Simple Mainframe Universe
Home Tutorials Interview Q&A Quiz Mainframe Memes Contact us About us

COBOL Troubleshooting


CLOSE reports an I/O error

Troubleshooting guide for CLOSE reports an I/O error. File handling bugs usually come from the FD or SELECT not matching the real dataset — the program opens fine and then misreads every record.

What it means

  • COBOL file I/O is declarative: SELECT, FD, and the JCL DD statement must all agree on organization, record format, and length.
  • When they disagree, the program rarely abends at OPEN — it reads shifted data or hits EOF at the wrong place.
  • FILE STATUS is the only reliable signal; without it, I/O errors are invisible.

Common causes

  • READ fails to detect EOF because the AT END clause is missing or the EOF flag is tested before the first READ.
  • OPEN EXTEND on a sequential file positions at end-of-file — a subsequent READ hits immediate EOF, which looks like an empty file.
  • CLOSE fails with file status 30/90+ because a previous WRITE had an unhandled error, or the DD was DUMMY.
  • FD RECORDING MODE / BLOCK CONTAINS disagrees with the real DCB — records arrive shifted or truncated.
  • Input record layout (copybook) is shorter than the real LRECL, so trailing fields land in the wrong positions.
  • Output fields shifted: numeric-edited or alphanumeric MOVEs into wrong offsets after a layout change.
  • Record count mismatch: header/trailer records counted as data, or a restart reprocessed part of the file.
  • Duplicate output: program writes the same record twice because the WRITE is inside a loop that also handles the AT END path.

How to diagnose

  • Always code FILE STATUS and DISPLAY it after OPEN/READ/WRITE/CLOSE during diagnosis — status 00 means success, anything else names the problem.
  • Compare FD record length against the dataset LRECL (check with ISPF 3.4 or LISTCAT) — they must match for fixed files.
  • For shifted fields: DISPLAY the first input record in hex and map each field offset against the copybook.
  • For EOF problems: verify the AT END clause exists on every READ and the EOF flag is initialized to "N" before the loop.
  • Check the JCL DD: DISP, DSN, and DCB on the DD can override what the program expects.

How to fix it

  • Add FILE STATUS to every SELECT and check it after each I/O verb; abend the step with a clear message on unexpected status.
  • Correct the FD/copybook to match the real LRECL, or fix the JCL DCB — one side must change so both agree.
  • For OPEN EXTEND followed by reads: CLOSE and re-OPEN INPUT, or use a separate SELECT for the read pass.
  • Move the WRITE out of the AT END handling path so the last record is written exactly once.
  • Count input records, output records, and rejects separately, and balance them in the trailer.

Example: FILE STATUS checked after every I/O verb

SELECT INPUT-FILE ASSIGN TO INFILE ORGANIZATION IS SEQUENTIAL FILE STATUS IS WS-FS-IN. * OPEN INPUT INPUT-FILE. IF WS-FS-IN NOT = "00" DISPLAY "OPEN FAILED, FS=" WS-FS-IN MOVE 16 TO RETURN-CODE GOBACK END-IF. READ INPUT-FILE AT END MOVE "Y" TO EOF-FLAG NOT AT END ADD 1 TO WS-IN-COUNT END-READ.

FILE STATUS "00" means success; any other value after OPEN/READ tells you exactly what went wrong.

Interview tip

  • Q: A job reads a file and processes zero records, but the file is not empty. What do you check?
  • A: First the FILE STATUS after OPEN — 35 means the dataset was not found, 39 means the FD and DCB disagree. Then I check whether the program opened the file EXTEND (which positions at EOF) and whether the AT END flag was initialized before the first READ.

Prevention checklist

  • Code FILE STATUS on every file and check it after every OPEN, READ, WRITE, and CLOSE.
  • Keep one copybook per layout shared by all programs reading the file.
  • Balance record counts (in = out + rejects) and abend the step on mismatch.
  • Test with empty files, one-record files, and files with bad trailing records.




© copyright mainframebug.com
Privacy Policy
MainframeBug Assistant