Common causes
- A fresh VPS, container or CI image without the unzip package installed
- The PHP zip extension is not installed for the CLI PHP (php-zip is per version, e.g. php8.3-zip)
- The extension is enabled for the web server's php.ini but not the CLI php.ini shown in the message
- Minimal Docker images (php:*-cli, alpine) that do not include libzip or unzip by default
- A Windows PHP install with extension=zip still commented out
How to fix it
- Install the unzip command. This is the preferred fix because it is faster than the PHP extension: sudo apt install unzip on Debian/Ubuntu, sudo dnf install unzip on RHEL/AlmaLinux, apk add unzip on Alpine.
- Install the PHP zip extension too. Install the package for your CLI version, e.g. sudo apt install php8.3-zip, and confirm with php -m | grep zip.
- Check the php.ini Composer reports. The message prints the CLI php.ini path. If you enable zip by editing php.ini (Windows), edit that exact file, not the one for Apache or FPM.
- Fix it in Docker or CI. Add unzip and the zip extension to your image (see the snippet) so CI does not fall back to source downloads and hit GitHub rate limits.
- Clear the cache and retry. Run composer clear-cache, delete the partially installed vendor/ folder and run composer install again. Packages should now show 'Extracting archive'.
Dockerfile (php:8.3-cli)
FROM php:8.3-cli
RUN apt-get update \
&& apt-get install -y --no-install-recommends git unzip libzip-dev \
&& docker-php-ext-install zip \
&& rm -rf /var/lib/apt/lists/*
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer How to stop it happening again
- Include unzip, git and php-zip in every server provisioning script and Docker base image
- Run composer diagnose on new environments before the first deploy
- Cache Composer's download cache in CI to reduce repeated downloads