AEIW: QZERO not handled
An AEIW abend means a READQ TD command found the transient data queue empty, or at its end, and the program didn't handle the QZERO condition. The program read the queue without checking whether anything was left.
Other names for this code
Also written as AEIW abend, CICS AEIW, abend AEIW, QZERO, CICS QZERO, AEIW QZERO, READQ TD empty.
What it means
Transient data (TD) queues pass records from one task to another, or to and from a sequential data set. An intrapartition queue lives inside CICS. Reading a record from it removes the record, so the next READQ TD gets the one after. An extrapartition queue is a z/OS data set, read from the start to the end.
When READQ TD finds no more records, CICS raises QZERO. For an intrapartition queue that means the queue is empty. For an extrapartition input queue it means the end of the data set was reached. QZERO is the normal way to know the queue has been drained, but its default action is to abend the task with AEIW. A program that codes RESP(WS-RESP) gets control back and can test for DFHRESP(QZERO).
Many TD readers are started by automatic transaction initiation (ATI). The queue has a trigger level, and when that many records are waiting, CICS starts the queue's transaction. IBM advises that such a task keep reading until QZERO, so it ends only when the queue is empty.
QZERO is not the same as QBUSY. QBUSY means another task is writing to or deleting a recoverable queue and no committed records are left yet. By default the read just waits, and QBUSY is raised only when NOSUSPEND is coded or a QBUSY handler is active.
Common causes
- An ATI-triggered program reads one record, or a fixed number, and assumes more are there.
- A read loop has no QZERO test and so fails on the read after the last record.
- Two tasks read the same queue. One drains it, and the other finds it empty.
- The transaction was started by hand or by a START when the queue had nothing in it.
- An extrapartition input data set had fewer records than the program expected, or was empty.
How to find the problem
- The terminal message
DFHAC2206names the transaction. In the dump, EIBFN shows READQ TD and EIBRSRCE names the queue. - Run
CEMT INQUIRE TDQUEUE(name)to see the queue type, how many items it holds, its trigger level and the transaction it starts. - Check how the failing task was started. A task started by a TD trigger runs the transaction named in the queue definition, so compare that with the failing transaction.
- Run the transaction under CEDF to step through the reads and see the response on the last one.
How to fix it
- Read in a loop and stop on QZERO. Put
WHEN DFHRESP(QZERO)in the EVALUATE after READQ TD and leave the loop there, then RETURN. - Treat QZERO as a normal result, not an error. Only log it when the program really expected data.
- If more than one task may read the same queue, make sure each can handle finding it empty.
- For an extrapartition queue, check that the job that builds the input data set ran and produced records before CICS reads it.
What it looks like
DFHDU0203I 10/18/2026 05:14:09 CICSPRD1 A transaction dump was taken for dumpcode: AEIW, Dumpid: 1/0082. DFHAC2206 05:14:09 CICSPRD1 Transaction TDRD failed with abend AEIW. Updates to local recoverable resources backed out.
IBM documentation
IBM documentation: AEIW. Use the documentation for your installed release.
Related codes
Questions
What is the difference between QZERO and QIDERR?
QZERO means the queue exists but has nothing left to read. QIDERR means CICS can't find a queue with that name. Their abends are AEIW and AEYH.
Why did an ATI task start when the queue was empty?
Usually another task read the records first. The trigger fired when the queue reached its trigger level, but by the time this task read it there was nothing left.
Does READQ TS raise QZERO at the end of a TS queue?
No. Temporary storage uses ITEMERR when you read past the last item. That leads to AEIZ, not AEIW.