ARTIFACTORY: Why Drupal Composer package downloads fail with 404 errors
Overview / IntroductionWhen proxying Drupal's Composer registry (packages.drupal.org) through an Artifactory Composer remote repository, Composer package metadata resolves correctly, but downloading the actual package archive (the "dist") fails with a 404 error. This issue occurs even though the exact same package version is reachable and downloadable directly from drupal.org's infrastructure outside of Artifactory.
Symptoms & error messages
-
A Composer remote repository is configured with its URL pointing to packages.drupal.org -
composer install or composer require fails while resolving Drupal contrib packages (e.g., drupal/devel, drupal/*), but works normally for Packagist-hosted packages. -
Zapping the remote repository's cache does not resolve the issue. -
The 404 error affects essentially every Drupal contrib package pulled through the repository, not just one specific package. -
The failed archive request returns a 404:
GET <JFROG_URL>/artifactory/api/composer/<repo-key>/vcs-dists/zip/project/<package>/<commit-sha>
→ HTTP 404 { "errors": [ { "status": 404, "message": "Could not find resource" } ] }-
The metadata request for the same package succeeds normally:
GET <JFROG_URL>/artifactory/api/composer/<repo-key>/p2/drupal/<package>.json → HTTP 200
Cause
Drupal's Composer registry returns metadata pointing to real dist URLs on git.drupalcode.org (drupal.org's self-hosted GitLab instance). Artifactory intentionally rewrites this into a self-referencing URL to proxy and cache the download, which is expected behavior.The failure occurs during the reconstruction of the real download request. This reconstruction depends on the repository's VCS Provider setting (vcsGitProvider), which defaults to GITHUB. The built-in provider templates (GITHUB, GITLAB, and BITBUCKET) all use relative paths that append to the repository's own configured url field. Because the repository's url is packages.drupal.org but the archives live on a completely different host (git.drupalcode.org), no built-in provider can construct a valid URL, resulting in a 404.
Step-by-step solution
Apply this fix directly on the affected Composer remote repository. No changes are required on the virtual repository.-
Navigate to the affected Composer remote repository configuration. -
In the VCS section, set the VCS Provider to Custom. -
Configure the download URL template to match git.drupalcode.org's plain web I archive format:
Plaintext
https://git.drupalcode.org/{0}/{1}/-/archive/{2}.{3}Alternatively, apply the fix via the REST API:Bash
curl -X POST "https://<JFROG_URL>/artifactory/api/repositories/<repo-key>" \
-H "Content-Type: application/json" \
-u "<user>:<token>" \
-d '{
"vcsGitProvider": "CUSTOM",
"vcsGitDownloadUrl": "https://git.drupalcode.org/{0}/{1}/-/archive/{2}.{3}"
}'
Verification
Do not rely solely on an HTTP 200 status code to confirm the fix works.-
Request the dist URL again after applying the fix, both directly against the Composer remote repository and through the virtual repository. -
Compare the checksum (sha256) of the file Artifactory returns against a checksum of the same archive downloaded directly from git.drupalcode.org for the exact same package and commit reference. -
Repeat the test against a second, different package to confirm the fix is not specific to a single cached response.
Related resources