{"record":{"id":"10464185c486e159","repo":"composer/composer","slug":"composer-rollback-failed-could-not-download-the-s","errorCode":null,"errorMessage":"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.","messagePattern":"Composer rollback failed: could not download the signature from (.+?) to verify the backup, aborting to avoid installing an unverified composer\\.phar\\. Retry once you are online\\.","errorType":"console","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/Composer/Command/SelfUpdateCommand.php","lineNumber":433,"sourceCode":"        // version and verify against it, exactly like the self-update download does.\n        [$version, $isTag] = $this->parseBackupVersion($rollbackVersion);\n\n        if (!extension_loaded('openssl') && $config->get('disable-tls')) {\n            $io->writeError('<warning>Skipping phar signature verification as you have disabled OpenSSL via config.disable-tls</warning>');\n        } elseif (!$isTag) {\n            // Snapshot/dev builds are not downloadable per-commit so no signature is published for them.\n            $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>');\n            if ($io->isInteractive() && !$io->askConfirmation('Do you want to roll back to this unverified backup anyway? [<comment>y/N</comment>] ', false)) {\n                $io->writeError('<warning>Rollback aborted.</warning>');\n\n                return 1;\n            }\n        } else {\n            $sigUrl = $baseUrl.'/download/'.$version.'/composer.phar.sig';\n            try {\n                $signature = $httpDownloader->get($sigUrl)->getBody();\n            } catch (TransportException $e) {\n                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);\n            }\n            if (null === $signature || '' === $signature) {\n                throw new \\RuntimeException('Composer rollback failed: an empty signature was downloaded from '.$sigUrl);\n            }\n            // Throws on mismatch, which aborts the rollback before setLocalPhar() installs the backup.\n            $this->verifyPhar($oldFile, $signature, true, $home, $sigUrl);\n        }\n\n        if (!$this->setLocalPhar($localFilename, $oldFile)) {\n            return 1;\n        }\n\n        return 0;\n    }\n\n    /**\n     * Checks if the downloaded/rollback phar is valid then moves it\n     *","sourceCodeStart":415,"sourceCodeEnd":451,"githubUrl":"https://github.com/composer/composer/blob/c435d285c9120efdca35696769c72ea9fdcc0466/src/Composer/Command/SelfUpdateCommand.php#L415-L451","documentation":"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.","triggerScenarios":"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).","commonSituations":"CI without network egress to getcomposer.org; DNS/proxy/firewall blocking the signature URL; transient outage; captive portal returning a non-404 error page.","solutions":["Restore network connectivity and retry `composer self-update --rollback`.","If a proxy is required, configure it via the standard http_proxy env / Composer config.","Verify reachability: `curl -I https://getcomposer.org/download/<version>/composer.phar.sig`.","As a last resort, reinstall the target version directly with `composer self-update <version>` (which also verifies the fresh download)."],"exampleFix":"// before\ncomposer self-update --rollback   # offline, signature download fails\n// after\n# bring network up, then\ncomposer self-update --rollback","handlingStrategy":"retry","validationCode":"// Confirm the signature URL is reachable before rollback\n$url = 'https://getcomposer.org/download/' . $version . '/composer.phar.sig';\n$headers = @get_headers($url);\nif ($headers === false || strpos($headers[0], '200') === false) {\n    fwrite(STDERR, \"Cannot reach signature URL $url. Check network/proxy.\\n\");\n    exit(1);\n}","typeGuard":null,"tryCatchPattern":"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}","preventionTips":["Ensure outbound HTTPS to getcomposer.org works before rollback.","Configure proxies via http_proxy / Composer config if needed.","Retry after restoring connectivity; the message explicitly suggests it."],"tags":["cli","self-update","rollback","network","security"],"backgroundTag":null,"analyzedSha":"c435d285c9120efdca35696769c72ea9fdcc0466","analyzedAt":"2026-08-07T18:58:23.525Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}