Set Bundler.settings[:ssl_ca_cert] to download gems#9610
Open
junaruga wants to merge 1 commit into
Open
Conversation
c00e6db to
722af3d
Compare
When `bundle install` connects with a certification (CA) to a private RubyGems
HTTPS server emulated by WEBrick, the connection to the
https://localhost:18443/versions succeeded, but the connection to download gems
failed with the following error.
```
+ /home/jaruga/var/git/ruby/rubygems/bin/bundle config set --local ssl_ca_cert /home/jaruga/git/report-bundler-bundle-config-set-ssl_ca_cert/tmp/client/ssl/ca.crt
...
+ /home/jaruga/var/git/ruby/rubygems/bin/bundle install -V
Running `bundle install --verbose` with bundler 4.1.0.dev
Resolving dependencies because there's no lockfile
HTTP GET https://localhost:18443/versions
HTTP 206 Partial Content https://localhost:18443/versions
HTTP GET https://localhost:18443/versions
HTTP 200 OK https://localhost:18443/versions
Fetching gem metadata from https://localhost:18443/
Looking up gems ["hello"]
Resolving dependencies...
Using bundler 4.1.0.dev
1: bundler (4.1.0.dev) from /home/jaruga/var/git/ruby/rubygems/bundler/bundler.gemspec
Fetching hello 0.1.0
Retrying download gem from https://localhost:18443/ due to error (2/4): Gem::RemoteFetcher::FetchError SSL_connect returned=1 errno=0 peeraddr=127.0.0.1:18443 state=error: certificate verify failed (unable to get local issuer certificate) (https://localhost:18443/gems/hello-0.1.0.gem)
Sleeping for 1.22 seconds before retry
Retrying download gem from https://localhost:18443/ due to error (3/4): Gem::RemoteFetcher::FetchError SSL_connect returned=1 errno=0 peeraddr=127.0.0.1:18443 state=error: certificate verify failed (unable to get local issuer certificate) (https://localhost:18443/gems/hello-0.1.0.gem)
Sleeping for 2.26 seconds before retry
Retrying download gem from https://localhost:18443/ due to error (4/4): Gem::RemoteFetcher::FetchError SSL_connect returned=1 errno=0 peeraddr=127.0.0.1:18443 state=error: certificate verify failed (unable to get local issuer certificate) (https://localhost:18443/gems/hello-0.1.0.gem)
Sleeping for 4.02 seconds before retry
Bundler::InstallError: Bundler::HTTPError: Could not download gem from https://localhost:18443/ due to underlying error <SSL_connect returned=1 errno=0 peeraddr=127.0.0.1:18443 state=error: certificate verify failed (unable to get local issuer certificate) (https://localhost:18443/gems/hello-0.1.0.gem)>
/home/jaruga/var/git/ruby/rubygems/bundler/lib/bundler/rubygems_integration.rb:406:in 'Bundler::RubygemsIntegration#download_gem'
/home/jaruga/var/git/ruby/rubygems/bundler/lib/bundler/source/rubygems.rb:531:in 'block in Bundler::Source::Rubygems#download_gem'
/home/jaruga/.local/ruby-4.1.0-debug-3ef48ef9c8-openssl-4.1.0-7194354488/lib/ruby/4.1.0+1/rubygems.rb:1068:in 'Gem.time'
/home/jaruga/var/git/ruby/rubygems/bundler/lib/bundler/source/rubygems.rb:530:in 'Bundler::Source::Rubygems#download_gem'
/home/jaruga/var/git/ruby/rubygems/bundler/lib/bundler/source/rubygems.rb:459:in 'Bundler::Source::Rubygems#fetch_gem'
/home/jaruga/var/git/ruby/rubygems/bundler/lib/bundler/source/rubygems.rb:443:in 'Bundler::Source::Rubygems#fetch_gem_if_possible'
/home/jaruga/var/git/ruby/rubygems/bundler/lib/bundler/source/rubygems.rb:575:in 'Bundler::Source::Rubygems#rubygems_gem_installer'
/home/jaruga/var/git/ruby/rubygems/bundler/lib/bundler/source/rubygems.rb:184:in 'Bundler::Source::Rubygems#download'
/home/jaruga/var/git/ruby/rubygems/bundler/lib/bundler/installer/gem_installer.rb:29:in 'Bundler::GemInstaller#download'
/home/jaruga/var/git/ruby/rubygems/bundler/lib/bundler/installer/parallel_installer.rb:148:in 'Bundler::ParallelInstaller#do_download'
/home/jaruga/var/git/ruby/rubygems/bundler/lib/bundler/installer/parallel_installer.rb:132:in 'block in Bundler::ParallelInstaller#worker_pool'
/home/jaruga/var/git/ruby/rubygems/bundler/lib/bundler/worker.rb:70:in 'Bundler::Worker#apply_func'
/home/jaruga/var/git/ruby/rubygems/bundler/lib/bundler/worker.rb:65:in 'block in Bundler::Worker#process_queue'
/home/jaruga/var/git/ruby/rubygems/bundler/lib/bundler/worker.rb:56:in 'Kernel#loop'
/home/jaruga/var/git/ruby/rubygems/bundler/lib/bundler/worker.rb:56:in 'Bundler::Worker#process_queue'
/home/jaruga/var/git/ruby/rubygems/bundler/lib/bundler/worker.rb:98:in 'block (2 levels) in Bundler::Worker#create_threads'
...
```
`Bundler::Fetcher` creates the connection object by the `#connection` calling
`#bundler_cert_store` storing `Bundler.settings[:ssl_ca_cert]` in the following
part. It is used in some parts.
bundler/lib/bundler/fetcher.rb
```
def bundler_cert_store
...
ssl_ca_cert = Bundler.settings[:ssl_ca_cert] ||
(Gem.configuration.ssl_ca_cert if
Gem.configuration.respond_to?(:ssl_ca_cert))
...
end
```
However in the case of downloading gems in Bundler,
Bundler calls `Bundler::Source::Rubygems#download_gem`
calling `Bundler::Fetcher#gem_remote_fetcher`
calling `Bundler::Fetcher::GemRemoteFetcher`
extending `Gem::RemoteFetcher` managing `@cert_files` for RubyGems.
Therefore, the `Bundler::Fetcher::GemRemoteFetcher` needs to update the `@cert_files`
by adding the value of the `Bundler.settings[:ssl_ca_cert]`.
As in the process of downloading gems,
`Gem::Request.configure_connection_for_https` is called, and it gets
`Gem.configuration.ssl_ca_cert`,
we don't need to add the value in the `Bundler::Fetcher::GemRemoteFetcher`.
According to the following logic, `@cert_files` is always not `nil`,
as `Dir.glob(patterns` returns Array. We don't need to consider the `nil` case.
lib/rubygems/remote_fetcher.rb
```
def initialize(proxy = nil, dns = nil, headers = {})
...
@cert_files = Gem::Request.get_cert_files
...
end
```
lib/rubygems/request.rb
```
def self.get_cert_files
pattern = File.expand_path("./ssl_certs/*/*.pem", __dir__)
Dir.glob(pattern)
end
```
Add unit tests for `Bundler::Fetcher::GemRemoteFetcher#initialize`.
722af3d to
ad9f1c7
Compare
junaruga
added a commit
to junaruga/ruby-pqc-test
that referenced
this pull request
Jun 10, 2026
* Install bundler from junaruga/rubygems fork branch wip/bundler-fix-bundle-config-set-ssl_ca_cert in all CI jobs * Use bundle config set --local ssl_ca_cert instead of SSL_CERT_FILE * Workaround for ruby/rubygems#9610 Assisted-by: Claude Code
junaruga
added a commit
to junaruga/ruby-pqc-test
that referenced
this pull request
Jun 10, 2026
* Install bundler from junaruga/rubygems fork branch wip/bundler-fix-bundle-config-set-ssl_ca_cert in all CI jobs * Use bundle config set --local ssl_ca_cert instead of SSL_CERT_FILE * Workaround for ruby/rubygems#9610 Assisted-by: Claude Code
Member
Author
|
Note I plan to add Bundler's PQC integration tests with the real ML-DSA, RSA certificates under |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue
When
bundle installconnects with a certification (CA) to a private RubyGems HTTPS server emulated by WEBrick, the connection to the https://localhost:18443/versions succeeded, but the connection to download gems failed with the following error.Reproducer
I prepared a minimal reproducer on the following repository. You can try for ruby/rubygems master branch.
https://github.com/junaruga/report-bundler-bundle-config-set-ssl_ca_cert
Cause & fix
Bundler::Fetchercreates the connection object by the#connectioncalling#bundler_cert_storestoringBundler.settings[:ssl_ca_cert]in the following part. It is used in some parts.bundler/lib/bundler/fetcher.rb
However in the case of downloading gems in Bundler, Bundler calls
Bundler::Source::Rubygems#download_gemcallingBundler::Fetcher#gem_remote_fetchercalling
Bundler::Fetcher::GemRemoteFetcherextending
Gem::RemoteFetchermanaging@cert_filesfor RubyGems.Therefore, the
Bundler::Fetcher::GemRemoteFetcherneeds to update the@cert_filesby adding the value of theBundler.settings[:ssl_ca_cert].As in the process of downloading gems,
Gem::Request.configure_connection_for_httpsis called, and it getsGem.configuration.ssl_ca_cert,we don't need to add the value in the
Bundler::Fetcher::GemRemoteFetcher.The backtrace is below.
According to the following logic,
@cert_filesis always notnil, asDir.glob(patternsreturns Array. We don't need to consider thenilcase.lib/rubygems/remote_fetcher.rb
lib/rubygems/request.rb
Add unit tests for
Bundler::Fetcher::GemRemoteFetcher#initialize.What was the end-user or developer problem that led to this PR?
The
bundle config set ssl_ca_certdoesn't work in the process of downloading gems.What is your fix for the problem, implemented in this PR?
Added the
Bundler.settings[:ssl_ca_cert]in the process of downloading gems.Make sure the following tasks are checked