composer/composer · error · RuntimeException

Composer rollback failed: could not download the signature f

Error message

Composer rollback failed: could not download the signature from ${sigUrl} to verify the backup, aborting to avoid installing an unverified composer.phar. Retry once you are online.

What it means

Thrown by rollback() when downloading the published signature for the backup version fails with a TransportException (non-404). Before installing a backup phar, Composer verifies it against the official signature; if the signature cannot be fetched the rollback is aborted rather than installing an unverified phar. It is an \RuntimeException chaining the TransportException, advising to retry when online.

Source

Thrown at src/Composer/Command/SelfUpdateCommand.php:433

        // version and verify against it, exactly like the self-update download does.
        [$version, $isTag] = $this->parseBackupVersion($rollbackVersion);

        if (!extension_loaded('openssl') && $config->get('disable-tls')) {
            $io->writeError('<warning>Skipping phar signature verification as you have disabled OpenSSL via config.disable-tls</warning>');
        } elseif (!$isTag) {
            // Snapshot/dev builds are not downloadable per-commit so no signature is published for them.
            $io->writeError('<warning>The signature of "'.$rollbackVersion.'" can not be verified as no signature is published for snapshot/dev builds. Make sure your data-dir ("'.$rollbackDir.'") is not writable by untrusted users.</warning>');
            if ($io->isInteractive() && !$io->askConfirmation('Do you want to roll back to this unverified backup anyway? [<comment>y/N</comment>] ', false)) {
                $io->writeError('<warning>Rollback aborted.</warning>');

                return 1;
            }
        } else {
            $sigUrl = $baseUrl.'/download/'.$version.'/composer.phar.sig';
            try {
                $signature = $httpDownloader->get($sigUrl)->getBody();
            } catch (TransportException $e) {
                throw new \RuntimeException('Composer rollback failed: could not download the signature from '.$sigUrl.' to verify the backup, aborting to avoid installing an unverified composer.phar. Retry once you are online.', 0, $e);
            }
            if (null === $signature || '' === $signature) {
                throw new \RuntimeException('Composer rollback failed: an empty signature was downloaded from '.$sigUrl);
            }
            // Throws on mismatch, which aborts the rollback before setLocalPhar() installs the backup.
            $this->verifyPhar($oldFile, $signature, true, $home, $sigUrl);
        }

        if (!$this->setLocalPhar($localFilename, $oldFile)) {
            return 1;
        }

        return 0;
    }

    /**
     * Checks if the downloaded/rollback phar is valid then moves it
     *

View on GitHub (pinned to c435d285c9)

Solutions

  1. Restore network connectivity and retry `composer self-update --rollback`.
  2. If a proxy is required, configure it via the standard http_proxy env / Composer config.
  3. Verify reachability: `curl -I https://getcomposer.org/download/<version>/composer.phar.sig`.
  4. As a last resort, reinstall the target version directly with `composer self-update <version>` (which also verifies the fresh download).

Example fix

// before
composer self-update --rollback   # offline, signature download fails
// after
# bring network up, then
composer self-update --rollback
Defensive patterns

Strategy: retry

Validate before calling

// Confirm the signature URL is reachable before rollback
$url = 'https://getcomposer.org/download/' . $version . '/composer.phar.sig';
$headers = @get_headers($url);
if ($headers === false || strpos($headers[0], '200') === false) {
    fwrite(STDERR, "Cannot reach signature URL $url. Check network/proxy.\n");
    exit(1);
}

Try / catch

try {\n    // run `composer self-update --rollback`\n} catch (\RuntimeException $e) {\n    if (str_contains($e->getMessage(), 'could not download the signature')) {\n        // transient network error -> back off and retry, or fix connectivity\n    }\n}

Prevention

When it happens

Trigger: Running `composer self-update --rollback` while offline or on a flaky network; the GET to `$baseUrl/download/<version>/composer.phar.sig` raises a TransportException that is not a 404 (SelfUpdateCommand.php:430-433).

Common situations: CI without network egress to getcomposer.org; DNS/proxy/firewall blocking the signature URL; transient outage; captive portal returning a non-404 error page.

Related errors


AI-assisted analysis of composer/composer@c435d285c9 (2026-08-07). Data as JSON: /api/errors/10464185c486e159. Report an issue: GitHub.