Handling Unrar Exit Codes in CI/CD Pipelines

This article explains how to reliably manage unrar exit codes within continuous integration and continuous deployment (CI/CD) pipelines. Standard automation pipelines automatically fail when a shell step yields a non-zero exit status, creating false-positive build failures when unrar emits warnings or non-fatal status codes. Below is an overview of standard unrar exit codes, the mechanism causing CI build breaks, and production-ready wrapper strategies to handle these codes cleanly across systems like GitHub Actions, GitLab CI, and Jenkins.

Understanding Unrar Exit Codes

By default, the unrar utility uses standard exit codes to signal whether an archive operation succeeded, encountered warnings, or failed completely:

  • 0 (SUCCESS): Extraction was successful without errors.
  • 1 (WARNING): Non-fatal error(s) occurred (e.g., some files could not be extracted, minor warnings).
  • 2 (FATAL_ERROR): A fatal error occurred (e.g., corrupt archive, memory access errors).
  • 3 (CRC_ERROR): CRC error; data is damaged.
  • 4 (LOCKED): Attempted to modify a locked archive.
  • 5 (WRITE_ERROR): Write error to disk.
  • 6 (OPEN_ERROR): File open error.
  • 7 (USER_ERROR): Incorrect command line syntax.
  • 8 (MEMORY_ERROR): Not enough memory for operation.
  • 9 (CREATE_ERROR): File create error.
  • 255 (USER_BREAK): Process interrupted by user.

In CI/CD environments configured with set -e (fail on any non-zero exit code), exit code 1 immediately halts the build, even if the required target files were extracted properly.

The Best Practice: Capture and Evaluate Exit Codes

The most reliable approach to handle unrar in a pipeline is to temporarily disable immediate exit on error, capture the return code, and evaluate it explicitly using a shell case statement.

Bash Wrapper Implementation

#!/usr/bin/env bash
set -eo pipefail

ARCHIVE_PATH="$1"
DEST_PATH="$2"

# Run unrar and capture exit code without failing the script immediately
set +e
unrar x -o+ -y "$ARCHIVE_PATH" "$DEST_PATH"
EXIT_CODE=$?
set -e

# Evaluate unrar response
case $EXIT_CODE in
    0)
        echo "Unrar completed successfully."
        ;;
    1)
        echo "::warning::Unrar completed with warnings (non-fatal errors)."
        # Do not exit; allow the build to proceed
        ;;
    2|3|4|5|6|7|8|9|255)
        echo "::error::Unrar failed with critical error code: $EXIT_CODE"
        exit "$EXIT_CODE"
        ;;
    *)
        echo "::error::Unrar encountered an unknown error: $EXIT_CODE"
        exit "$EXIT_CODE"
        ;;
esac

Adding File Verification Steps

Because exit code 1 indicates that at least one file had extraction issues, simply ignoring it can lead to silent failures downstream if an essential asset is missing. Always follow extraction with an explicit check for the required build artifacts:

# Verify the critical file exists after unrar execution
if [ ! -f "$DEST_PATH/required_payload.bin" ]; then
    echo "Fatal: Critical files are missing after extraction."
    exit 1
fi

Inline Handling in CI Configuration Files

If creating an external wrapper script is not ideal, handle the exit code inline within your CI pipeline configuration:

GitHub Actions

- name: Extract Archive
  run: |
    set +e
    unrar x -o+ -y package.rar dist/
    CODE=$?
    set -e
    
    if [ $CODE -ne 0 ] && [ $CODE -ne 1 ]; then
      echo "Extraction failed with exit code $CODE"
      exit $CODE
    fi

GitLab CI

extract_artifacts:
  stage: build
  script:
    - |
      unrar x -o+ -y package.rar dist/ || CODE=$?
      if [ -n "$CODE" ] && [ "$CODE" -gt 1 ]; then
        echo "Fatal unrar error: $CODE"
        exit $CODE
      fi

This pattern guarantees that non-critical archive warnings do not block CI/CD stages while ensuring true corruption, write failures, or missing files continue to halt deployment execution.