DEV Community

umzzil nng
umzzil nng

Posted on Originally published at oraerror.com

Oracle ORA-06556 Error: Causes and Solutions Complete Guide

ORA-06556: The Pipe Is Empty, Cannot Fulfill the UNPACK_MESSAGE Request

ORA-06556 is an Oracle error that occurs when DBMS_PIPE.UNPACK_MESSAGE is called but the pipe buffer contains no message to unpack. This typically happens when DBMS_PIPE.RECEIVE_MESSAGE either was not called beforehand, timed out, or returned a non-zero status that was ignored. Understanding the correct call sequence of DBMS_PIPE is essential to avoiding this error in inter-process communication (IPC) scenarios.


Top 3 Causes

1. Calling UNPACK_MESSAGE Without Checking RECEIVE_MESSAGE Return Value

RECEIVE_MESSAGE returns 0 on success, 1 on timeout, and 3 on error. If you skip the return value check and call UNPACK_MESSAGE directly, Oracle throws ORA-06556 because the buffer is empty.

-- WRONG: No return value check
DECLARE
  v_status  INTEGER;
  v_message VARCHAR2(4000);
BEGIN
  v_status := DBMS_PIPE.RECEIVE_MESSAGE('MY_PIPE', 5);
  -- Missing IF v_status = 0 check!
  DBMS_PIPE.UNPACK_MESSAGE(v_message); -- ORA-06556 if pipe is empty
END;
/

-- CORRECT: Always validate return status
DECLARE
  v_status  INTEGER;
  v_message VARCHAR2(4000);
BEGIN
  v_status := DBMS_PIPE.RECEIVE_MESSAGE('MY_PIPE', 5);
  IF v_status = 0 THEN
    DBMS_PIPE.UNPACK_MESSAGE(v_message);
    DBMS_OUTPUT.PUT_LINE('Message: ' || v_message);
  ELSIF v_status = 1 THEN
    DBMS_OUTPUT.PUT_LINE('Timeout: no message in pipe.');
  ELSE
    DBMS_OUTPUT.PUT_LINE('Error, status: ' || v_status);
  END IF;
END;
/
Enter fullscreen mode Exit fullscreen mode

2. Timeout Occurred Before Message Was Sent

In multi-session environments, the sender may be delayed. If RECEIVE_MESSAGE times out (returns 1) and the code proceeds to UNPACK_MESSAGE anyway, ORA-06556 is raised. Implementing a retry loop resolves this.

DECLARE
  v_status    INTEGER;
  v_message   VARCHAR2(4000);
  v_retry     INTEGER := 0;
  v_max_retry INTEGER := 3;
BEGIN
  LOOP
    v_status := DBMS_PIPE.RECEIVE_MESSAGE('MY_PIPE', 5);
    IF v_status = 0 THEN
      DBMS_PIPE.UNPACK_MESSAGE(v_message);
      DBMS_OUTPUT.PUT_LINE('Received: ' || v_message);
      EXIT;
    ELSIF v_status = 1 AND v_retry < v_max_retry THEN
      v_retry := v_retry + 1;
      DBMS_OUTPUT.PUT_LINE('Retry ' || v_retry || ' of ' || v_max_retry);
    ELSE
      DBMS_OUTPUT.PUT_LINE('Failed after retries or error occurred.');
      EXIT;
    END IF;
  END LOOP;
END;
/
Enter fullscreen mode Exit fullscreen mode

3. Sender Did Not Call PACK_MESSAGE Before SEND_MESSAGE

If the sender skips DBMS_PIPE.PACK_MESSAGE, an empty message may be sent or no message is placed in the pipe at all, leaving the receiver with nothing to unpack. Always pair PACK_MESSAGE with SEND_MESSAGE.

-- Sender side (correct pattern)
DECLARE
  v_status INTEGER;
BEGIN
  DBMS_PIPE.PACK_MESSAGE('Hello from sender!'); -- Must call before SEND
  v_status := DBMS_PIPE.SEND_MESSAGE('MY_PIPE', 10);
  IF v_status = 0 THEN
    DBMS_OUTPUT.PUT_LINE('Message sent successfully.');
  ELSE
    DBMS_OUTPUT.PUT_LINE('Send failed, status: ' || v_status);
  END IF;
END;
/

-- Check pipe status (requires DBA privilege)
SELECT name, items, size_used, size_limit
FROM   v$db_pipes
WHERE  name = 'MY_PIPE';
Enter fullscreen mode Exit fullscreen mode

Quick Fix Solutions

  1. Always check the return value of RECEIVE_MESSAGE before calling UNPACK_MESSAGE. Use IF v_status = 0 as a gate.
  2. Implement retry logic with a maximum retry count and timeout to handle delayed senders gracefully.
  3. Purge stale pipes if the pipe is in an unknown state using DBMS_PIPE.PURGE('MY_PIPE').
  4. Verify pipe names match exactly on both sender and receiver sides — pipe names are case-sensitive.

Prevention Tips

  • Build a shared wrapper procedure around DBMS_PIPE calls that enforces return value validation, retry logic, and logging by default. This prevents junior developers from making the classic mistake of skipping the status check.
  • Monitor pipe activity regularly using V$DB_PIPES. Set up alerts when pipe item counts grow unexpectedly, indicating a consumer is not reading messages correctly, which could lead to buffer overflow or stale state errors down the line.

📖 Want a more detailed guide?
Check out the full in-depth version (Korean) on oraerror.com — includes detailed analysis, additional SQL examples, and prevention tips.

Top comments (0)