Overview
Calling the Get RubyGem Version List REST API against a virtual Gems repository can return HTTP 500 for some gems, while the same request against a remote member of that virtual repository returns HTTP 200. This issue is commonly seen with dependency tools that query the versions API, and can be reproduced using curl.
The API is documented here: Get RubyGem Version List
GET /artifactory/api/gems/<REPO_KEY>/api/v1/versions/<GEM_NAME>.json
GET /artifactory/api/gems/<REPO_KEY>/api/v1/versions/<GEM_NAME>.yaml
Symptoms & Error Messages
{
"errors" : [ {
"status" : 500,
"message" : "Internal Server Error"
} ]
}-
The exact same request against the remote Gems repository (the member that proxies rubygems.org or another upstream) returns HTTP 200 and a version list.
-
Not every gem fails. Gems with large or mixed version sets (for example rack, nokogiri, fastlane) are typical. Other gems (for example tzinfo) can succeed on the same virtual repository.
-
A virtual repository that contains only the remote member can still return HTTP 500. A local-only virtual repository is not required to reproduce the issue.
Log Signatures
artifactory-request.log:
GET|/api/gems/<virtual-repo>/api/v1/versions/<gem>.json|500
artifactory-service.log:
[WARN ] [...] [PackageVersionsMerger:103] [...] - Error while trying to merge data from
<virtual-repo> error: Comparison method violates its general contract!
Cause
The virtual versions API merges version lists from member repositories, then sorts that merged list before returning it. The remote versions API streams the upstream response and does not perform this sort, which is why remote requests succeed while virtual requests fail.
By default, Artifactory sorts PackageVersion objects with a SemVer-oriented comparator. Real RubyGems version lists mix numeric versions, prereleases (e.g., 1.0.0.rc1), and platform suffixes. That mix is not a consistent total order for the default comparator. Java’s sort then fails with Comparison method violates its general contract!, and the API returns HTTP 500.
Setting artifactory.rubygems.aligned.version.comparator=true (which is set to false by default) switches to a RubyGems-aligned comparator:
-
Each version string is split into numeric and alphabetic segments (example: 1.0.0.rc1 → [1, 0, 0, "rc", 1]).
-
Segments are compared in order. A string (prerelease) segment is treated as lower than a numeric segment, matching RubyGems (1.0.0.rc1 < 1.0.0.1).
-
The sort completes, allowing the virtual API to return HTTP 200.
Note:
Enabling the property can change the order of versions in the virtual API response compared with the default comparator. It does not change compact index (/versions), gem install layout, or the remote versions API (which already worked).
This comparator was introduced as a feature flag (default false) under RTDEV-50987 and became available starting with Artifactory version 7.111.4 for Self-Hosted deployments. Follow-up work for the virtual Get RubyGem Version List HTTP 500 issue, including YAML requests and additional comparator cases, is tracked under RTDEV-57187 (Artifactory 7.111.9 Self-Managed). The property remains off by default on later versions, so the HTTP 500 error can still appear until the property is manually enabled.
Step-by-Step Solution
Enable the RubyGems-aligned version comparator and restart Artifactory.
Self-Hosted
-
Edit $JFROG_HOME/artifactory/var/etc/artifactory/artifactory.system.properties.
-
Add the following property:
artifactory.rubygems.aligned.version.comparator=true
-
Restart Artifactory so the property is loaded.
Helm
System properties can be passed via javaOpts. See How to modify artifactory.system.properties in artifactory and artifactory-ha chart.
Example for the Artifactory Helm chart:
artifactory:
javaOpts:
other: "-Dartifactory.rubygems.aligned.version.comparator=true"
SaaS
Open a Support ticket. Support can apply the property on the instance.
Verification
After the restart, retry a gem that previously returned 500:
curl -u <USER>:<TOKEN>
"https://<HOST>/artifactory/api/gems/<VIRTUAL_REPO>/api/v1/versions/rack.json"
Expected: HTTP 200 and a JSON array of versions.
Related Resources