Description
Chef's apt_repository resource does not provide behavioral parity with Ubuntu's add-apt-repository command when configuring Launchpad PPAs.
When adding a PPA, apt_repository attempts to retrieve the repository signing key through the GPG/HKP keyserver path using keyserver.ubuntu.com. On a system where IPv6 routing to keyserver.ubuntu.com is broken or unavailable, the key retrieval attempts the non-functional IPv6 route and does not successfully fall back to the working IPv4 path.
In contrast, Ubuntu's add-apt-repository successfully configures the same PPAs on the same host by querying LaunchPad's HTTPS API.
As a result, using Chef's native apt_repository resource is less reliable than shelling out to add-apt-repository for this use case.
Chef Version
19
Platform Version
Ubuntu 22.04
Replication Case
On an Ubuntu host where:
- IPv6 DNS resolution for
keyserver.ubuntu.com is available
- IPv6 connectivity to
keyserver.ubuntu.com is unavailable or has a dead route
- IPv4 connectivity is functional
Verify that the PPAs can be added successfully using Ubuntu's add-apt-repository:
sudo add-apt-repository -y ppa:longsleep/golang-backports
sudo add-apt-repository -y ppa:dotnet/backports
Then attempt to configure the equivalent repositories using Chef:
apt_repository 'golang-backports' do
uri 'ppa:longsleep/golang-backports'
action :add
end
apt_repository 'dotnet-backports' do
uri 'ppa:dotnet/backports'
action :add
end
Expected Behavior
Chef's apt_repository resource should successfully configure a Launchpad PPA under the same network conditions where Ubuntu's add-apt-repository succeeds.
Ideally, PPA handling should use the current Launchpad/Ubuntu mechanism for retrieving repository signing keys rather than depending on direct HKP access to keyserver.ubuntu.com.
At minimum, failure to reach the keyserver over IPv6 should not prevent key retrieval when IPv4 connectivity is available.
Actual Results
apt_repository attempts to retrieve the PPA signing key through keyserver.ubuntu.com using the GPG/HKP keyserver path.
When the host has a non-functional IPv6 route to the keyserver, key retrieval fails rather than successfully using the available IPv4 path.
The equivalent:
add-apt-repository -y ppa:<owner>/<repository>
succeeds on the same system.
This means a Chef recipe must potentially bypass the native apt_repository resource and execute add-apt-repository directly to obtain the behavior already provided by the operating system.
Client Output
Recipe: lessons::compiled_lang
* apt_package[openjdk-17-jdk, curl, build-essential] action install[2026-08-15T23:47:48+00:00] INFO: Processing apt_package[openjdk-17-jdk, curl, build-essential] action install (lessons::compiled_lang line 67)
[2026-08-15T23:47:48+00:00] DEBUG: apt_package[openjdk-17-jdk, curl, build-essential] is already installed - nothing to do
(up to date)
* apt_repository[ppa-dotnet-backports] action add[2026-08-15T23:47:48+00:00] INFO: Processing apt_repository[ppa-dotnet-backports] action add (lessons::compiled_lang line 40)
* execute[apt-cache gencaches] action nothing[2026-08-15T23:47:48+00:00] INFO: Processing execute[apt-cache gencaches] action nothing (lessons::compiled_lang line 549)
(skipped due to action :nothing)
[2026-08-15T23:47:48+00:00] DEBUG: Skipping execute[apt-cache gencaches] due to action :nothing
* apt_update[ppa-dotnet-backports] action nothing[2026-08-15T23:47:48+00:00] INFO: Processing apt_update[ppa-dotnet-backports] action nothing (lessons::compiled_lang line 556)
(skipped due to action :nothing)
[2026-08-15T23:47:48+00:00] DEBUG: Skipping apt_update[ppa-dotnet-backports] due to action :nothing
* execute[install-key 45A3F127159BE9E5017811C62125B164E8E5D3FA] action run[2026-08-15T23:47:48+00:00] INFO: Processing execute[install-key 45A3F127159BE9E5017811C62125B164E8E5D3FA] action run (lessons::compiled_lang line 438)
[execute] gpg: keyserver receive failed: No route to host
================================================================================
Error executing action `run` on resource 'execute[install-key 45A3F127159BE9E5017811C62125B164E8E5D3FA]'
================================================================================
Mixlib::ShellOut::ShellCommandFailed
------------------------------------
Expected process to exit with [0], but received '2'
---- Begin output of gpg --no-default-keyring --keyring /etc/apt/keyrings/ppa-dotnet-backports.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv 45A3F127159BE9E5017811C62125B164E8E5D3FA ----
STDOUT:
STDERR: gpg: keyserver receive failed: No route to host
---- End output of gpg --no-default-keyring --keyring /etc/apt/keyrings/ppa-dotnet-backports.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv 45A3F127159BE9E5017811C62125B164E8E5D3FA ----
Ran gpg --no-default-keyring --keyring /etc/apt/keyrings/ppa-dotnet-backports.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv 45A3F127159BE9E5017811C62125B164E8E5D3FA returned 2
Resource Declaration:
---------------------
# In /opt/chef/embedded/lib/ruby/gems/3.4.0/gems/chef-19.3.14/lib/chef/resource/apt_repository.rb
438: execute "install-key #{key}" do
439: command cmd
440: default_env true
441: sensitive new_resource.sensitive
442: not_if do
443: keyring_key_is_present?(keyring, key.upcase) && keyring_key_is_valid?(keyring, key.upcase)
444: end
445: notifies :run, "execute[apt-cache gencaches]", :immediately
446: end
447:
Compiled Resource:
------------------
# Declared in /opt/chef/embedded/lib/ruby/gems/3.4.0/gems/chef-19.3.14/lib/chef/resource/apt_repository.rb:438:in 'install_key_from_keyserver_to_keyring'
execute("install-key 45A3F127159BE9E5017811C62125B164E8E5D3FA") do
action [:run]
default_guard_interpreter :execute
command "gpg --no-default-keyring --keyring /etc/apt/keyrings/ppa-dotnet-backports.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv 45A3F127159BE9E5017811C62125B164E8E5D3FA"
declared_type :execute
cookbook_name "lessons"
recipe_name "compiled_lang"
default_env true
not_if { #code block }
end
System Info:
------------
chef_version=19.3.14
platform=ubuntu
platform_version=22.04
ruby=ruby 3.4.9 (2026-03-11 revision 76cca827ab) +PRISM [x86_64-linux]
program_name=/opt/chef/bin/chef-client
executable=/opt/chef/bin/chef-client
================================================================================
Error executing action `add` on resource 'apt_repository[ppa-dotnet-backports]'
================================================================================
Mixlib::ShellOut::ShellCommandFailed
------------------------------------
execute[install-key 45A3F127159BE9E5017811C62125B164E8E5D3FA] (lessons::compiled_lang line 438) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit with [0], but received '2'
---- Begin output of gpg --no-default-keyring --keyring /etc/apt/keyrings/ppa-dotnet-backports.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv 45A3F127159BE9E5017811C62125B164E8E5D3FA ----
STDOUT:
STDERR: gpg: keyserver receive failed: No route to host
---- End output of gpg --no-default-keyring --keyring /etc/apt/keyrings/ppa-dotnet-backports.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv 45A3F127159BE9E5017811C62125B164E8E5D3FA ----
Ran gpg --no-default-keyring --keyring /etc/apt/keyrings/ppa-dotnet-backports.gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv 45A3F127159BE9E5017811C62125B164E8E5D3FA returned 2
Resource Declaration:
---------------------
# In /var/chef/cache/cookbooks/lessons/libraries/helpers.rb
40: apt_repository pkg['apt_repository'].gsub(/[^A-Za-z0-9_.-]/, '-') do
41: uri pkg['apt_repository']
42: action :add
43: end
44: elsif pkg['add_apt_repo']
Compiled Resource:
------------------
# Declared in /var/chef/cache/cookbooks/lessons/libraries/helpers.rb:40:in 'Lessons::Helpers#lessons_install'
apt_repository("ppa-dotnet-backports") do
action [:add]
default_guard_interpreter :default
declared_type :apt_repository
cookbook_name "lessons"
recipe_name "compiled_lang"
uri "ppa:dotnet/backports"
repo_name "ppa-dotnet-backports"
end
System Info:
------------
chef_version=19.3.14
platform=ubuntu
platform_version=22.04
ruby=ruby 3.4.9 (2026-03-11 revision 76cca827ab) +PRISM [x86_64-linux]
program_name=/opt/chef/bin/chef-client
executable=/opt/chef/bin/chef-client
Stacktrace
Description
Chef's
apt_repositoryresource does not provide behavioral parity with Ubuntu'sadd-apt-repositorycommand when configuring Launchpad PPAs.When adding a PPA,
apt_repositoryattempts to retrieve the repository signing key through the GPG/HKP keyserver path usingkeyserver.ubuntu.com. On a system where IPv6 routing tokeyserver.ubuntu.comis broken or unavailable, the key retrieval attempts the non-functional IPv6 route and does not successfully fall back to the working IPv4 path.In contrast, Ubuntu's
add-apt-repositorysuccessfully configures the same PPAs on the same host by querying LaunchPad's HTTPS API.As a result, using Chef's native
apt_repositoryresource is less reliable than shelling out toadd-apt-repositoryfor this use case.Chef Version
19
Platform Version
Ubuntu 22.04
Replication Case
On an Ubuntu host where:
keyserver.ubuntu.comis availablekeyserver.ubuntu.comis unavailable or has a dead routeVerify that the PPAs can be added successfully using Ubuntu's
add-apt-repository:Then attempt to configure the equivalent repositories using Chef:
Expected Behavior
Chef's
apt_repositoryresource should successfully configure a Launchpad PPA under the same network conditions where Ubuntu'sadd-apt-repositorysucceeds.Ideally, PPA handling should use the current Launchpad/Ubuntu mechanism for retrieving repository signing keys rather than depending on direct HKP access to
keyserver.ubuntu.com.At minimum, failure to reach the keyserver over IPv6 should not prevent key retrieval when IPv4 connectivity is available.
Actual Results
apt_repositoryattempts to retrieve the PPA signing key throughkeyserver.ubuntu.comusing the GPG/HKP keyserver path.When the host has a non-functional IPv6 route to the keyserver, key retrieval fails rather than successfully using the available IPv4 path.
The equivalent:
succeeds on the same system.
This means a Chef recipe must potentially bypass the native
apt_repositoryresource and executeadd-apt-repositorydirectly to obtain the behavior already provided by the operating system.Client Output
Stacktrace