Problem

Original Problem

When updating with sudo pacman -Syyu, after downloading all update packages, pacman tries to download and import required keys. However, none of the keys can be imported:

 Total (78/78)                                         819.0 MiB  7.89 MiB/s 01:44 [###############################################] 100%
(79/79) checking keys in keyring                                                   [###############################################] 100%
downloading required keys...
:: Import PGP key 7A4E76095D8A52E4, "Antonio Rojas <[email protected]>"? [Y/n] y
error: key "7A4E76095D8A52E4" could not be imported
:: Import PGP key 150C200743ED46D8, "Mark Wagie <[email protected]>"? [Y/n] y
error: key "150C200743ED46D8" could not be imported
:: Import PGP key 539DFD48135182EF, "Juergen Hoetzel <[email protected]>"? [Y/n] y
error: key "539DFD48135182EF" could not be imported

Attempted Fixes

Tried to update pacman mirrors and refresh keys via:

sudo pacman-mirrors --continent
sudo pacman-key --refresh-keys && sudo pacman-key --populate

Mirror update succeeds, but key refresh shows the following error for each key it tries to refresh:

snowsr sudo pacman-key --refresh-keys && sudo pacman-key --populate
gpg: checking the trustdb
gpg: [don't know]: invalid packet (ctb=00)
gpg: keyring_get_keyblock: read error: Invalid packet
gpg: keyring_get_keyblock failed: Invalid keyring
gpg: failed to rebuild keyring cache: Invalid keyring
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: [don't know]: invalid packet (ctb=00)
gpg: keyring_get_keyblock: read error: Invalid packet
gpg: keydb_get_keyblock failed: Invalid keyring
gpg: validate_key_list failed
gpg: [don't know]: invalid packet (ctb=00)
gpg: keydb_search failed: Invalid packet
gpg: checking the trustdb
gpg: [don't know]: invalid packet (ctb=00)
gpg: keyring_get_keyblock: read error: Invalid packet
gpg: keyring_get_keyblock failed: Invalid keyring
gpg: failed to rebuild keyring cache: Invalid keyring
gpg: marginals needed: 3  completes needed: 1  trust model: pgp
gpg: [don't know]: invalid packet (ctb=00)
gpg: keyring_get_keyblock: read error: Invalid packet
gpg: keydb_get_keyblock failed: Invalid keyring
gpg: validate_key_list failed
gpg: error retrieving '[email protected]' via WKD: No data
gpg: error reading key: No data
gpg: [don't know]: invalid packet (ctb=00)
gpg: keyserver refresh failed: Invalid packet
==> ERROR: Could not update key: A04F9397CDFD6BB0

I have also changed DbOptinal to DbNever in pacman.conf . Still no magic.


Solution

Method

  • I followed instructions here. The blog provides a bash script that can fully “reset” pacman (mirrors, keys, trustdbs, etc.)
  • Running the downloaded script with --aggressive flag solves the problem.

Code

#!/usr/bin/env bash
# This script is copied from "https://forum.manjaro.org/t/howto-work-around-gpg-verification-issue-on-left-behind-systems/125822"
 
set -o errexit  #>Exit when a command fails (returns non-zero)
set -o pipefail #>Exit when a command within a pipeline fail (returns non-zero)
set -o nounset  #>Forbid to use unset
 
# Reset language to defaultx
export LANG=C
 
# Switch to root account
RunasRoot () { sudo --login --user=root "$@"; }
 
# Colors for messages
PrintInfo () { printf '\e[32m[INFO]\e[0m \e[33m%s\e[0m\n' "$1"; }
PrintError () { printf '\e[31m[ERROR]\e[0m \e[33m%s\e[0m\n' "$1"; }
PrintQuestion () { printf '\e[35m[QUESTION]\e[0m \e[33m%s\e[0m\n' "$1"; }
 
RmLockFiles () 
{
   PrintInfo "Remove lock files of pamac and pacman"
   RunasRoot find /var/tmp/pamac/ -type f -iname "*db.lck" -exec rm --force --verbose "{}" \;
   RunasRoot find /var/lib/pacman/ -type f -iname "*db.lck" -exec rm --force --verbose "{}" \;
}
 
AskForUpgrade ()
{
   PrintInfo "Performing a full upgrade with pacman"
   while true; do
      PrintQuestion "Do you want to continue? [Yy/Nn] (Be aware that a full upgrade needs enough ram on a live session)"
      read -p "> [Yy/Nn] " yn
      case $yn in
      [Yy]*) 
         RunasRoot pacman --sync --refresh --refresh --sysupgrade --sysupgrade --noconfirm
         PrintInfo "Done. Note that you need to refresh the database for pamac also."
         break
      ;;
      [Nn]*) 
         break
      ;;
      *)
         PrintError "No valid answer. Continue." && continue ;;
      esac
   done
}
 
AskForRefreshKeys ()
{
   PrintInfo "Refresh GnuPG Database of pacman from the Internet"
   while true; do
      PrintQuestion "Do you want to continue? [Yy/Nn] (Note that this can take a while.)"
      read -p "> [Yy/Nn] " yn
      case $yn in
      [Yy]*) 
         RunasRoot pacman-key --refresh-keys && break
      ;;
      [Nn]*) 
         break
      ;;
      *)
         PrintError "No valid answer. Continue." && continue ;;
      esac
   done
}
 
AskForRemoveCache ()
{
   PrintInfo "Remove cached software packages [optional]"
   while true; do
      PrintQuestion "Delete them? [Yy/Nn]"
      read -p "[Yy/Nn] > " yn
      case $yn in
      [Yy]*)
         PrintInfo "Removing package cache"
         RunasRoot pacman --sync --clean --clean --noconfirm
         if [[ $(ls /var/cache/pacman/pkg/ |wc -l) != 0]]; then
            RunasRoot find /var/cache/pacman/pkg/ -type f -exec rm --force --verbose "{}" \;
         fi
      ;;
      [Nn]*) 
         break
      ;;
      *)
         PrintError "No valid answer." && continue ;;
      esac
   done
}
 
BasicMethod ()
{
   RmLockFiles
 
   PrintInfo "Refresh Package Database"
   RunasRoot pacman --sync --refresh --refresh
 
   PrintInfo "Populate local keyrings to the GnuPG Database of pacman"
   RunasRoot pacman-key --populate archlinux manjaro
 
   AskForRefreshKeys
 
   AskForUpgrade
}
 
ModerateMethod ()
{
   RmLockFiles
 
   PrintInfo "Remove Pacman's GnuPG Database"
   RunasRoot find /etc/pacman.d/gnupg/ -exec rm --recursive --force --verbose "{}" \;
 
   PrintInfo "Initilize Pacman's GnuPG Database"
   RunasRoot pacman-key --init
 
   PrintInfo "Populate local keyrings to Pacman's GnuPG Database"
   RunasRoot pacman-key --populate archlinux manjaro
 
   AskForRefreshKeys
 
   AskForRemoveCache
 
   AskForUpgrade
}
 
AggressiveMethod ()
{
   RmLockFiles
   
   PrintInfo "Switch to global mirror (Manjaro's CDN)"
   RunasRoot pacman-mirrors --country Global
   RunasRoot pacman-mirrors --fasttrack 5
 
   PrintInfo "Remove Pacman's GnuPG Database"
   RunasRoot find /etc/pacman.d/gnupg/ -exec rm --recursive --force --verbose "{}" \;
 
   PrintInfo "Initilize Pacman's GnuPG Database"
   RunasRoot pacman-key --init
 
   PrintInfo "Removing package cache"
   RunasRoot pacman --sync --clean --clean --noconfirm
   if [[ $(ls /var/cache/pacman/pkg/ |wc -l) != 0]]; then
      RunasRoot find /var/cache/pacman/pkg/ -type f -exec rm --force --verbose "{}" \;
   fi
 
   PrintInfo "Create a temporary folder in /tmp"
   TMPDIR="$(mktemp -d)"
   PrintInfo "${TMPDIR}"
 
   PrintInfo "Copy /etc/pacman.conf to ${TMPDIR}/pacman.conf and disable temporarily gpg verification."
   RunasRoot cp "/etc/pacman.conf" "${TMPDIR}/pacman.conf"
   RunasRoot sed --in-place --regexp-extended 's/^(SigLevel).+$/\1 = Never/g' "${TMPDIR}/pacman.conf"
 
   PrintInfo "Download the newest packages which contains the gpg keyrings in ${TMPDIR}"
   RunasRoot pacman --sync --refresh --downloadonly --noconfirm --cachedir "${TMPDIR}" --config "${TMPDIR}/pacman.conf" archlinux-keyring manjaro-keyring gnupg --overwrite "*"
 
   PrintInfo "Install temporarily downloaded keyring packages"
   RunasRoot pacman --upgrade --noconfirm --config "${TMPDIR}/pacman.conf" $(find ${TMPDIR} -type f -name "*.tar.*")
 
   PrintInfo "Remove temporary directory: ${TMPDIR}"
   RunasRoot find "${TMPDIR}" -type f -exec rm --recursive --force --verbose "{}" \;
   RunasRoot rmdir --verbose "${TMPDIR}"
 
   PrintInfo "Switch to a local mirror by Geolocation"
   RunasRoot pacman-mirrors --geoip
   RunasRoot pacman-mirrors --fasttrack 5
 
   AskForRefreshKeys
 
   AskForUpgrade
 
}
 
HelpPage ()
{
   printf "\n\t%s\n" "Method 1 - Basic"
   printf "\t%s\n" "1. Remove lock files of pamac and pacman"
   printf "\t%s\n" "2. Refresh Package Database"
   printf "\t%s\n" "3. Populate local keyrings to the GnuPG Database of pacman"
   printf "\t%s\n" "4. Refresh GnuPG Database of pacman from the Internet [optional]"
   printf "\t%s\n" "5. Performing a full upgrade with pacman [optional]"
 
   printf "\n\t%s\n" "Method 2 - Moderate"
   printf "\t%s\n" "1. Remove lock files of pamac and pacman"
   printf "\t%s\n" "2. Remove Pacman's GnuPG Database"
   printf "\t%s\n" "3. Initilize Pacman's GnuPG Database"
   printf "\t%s\n" "4. Populate local keyrings to Pacman's GnuPG Database"
   printf "\t%s\n" "5. Refresh GnuPG Database of pacman from the Internet [optional]"
   printf "\t%s\n" "6. Remove cached software packages [optional]"
   printf "\t%s\n" "7. Performing a full upgrade with pacman [optional]"
 
   printf "\n\t%s\n" "Method 3 - Aggressive"
   printf "\t%s\n" "1. Remove lock files of pamac and pacman"
   printf "\t%s\n" "2. Switch to global mirror (Manjaro's CDN)"
   printf "\t%s\n" "3. Remove Pacman's GnuPG Database"
   printf "\t%s\n" "4. Initilize Pacman's GnuPG Database"
   printf "\t%s\n" "5. Remove cached software packages"
   printf "\t%s\n" "6. Create a temporary folder in /tmp"
   printf "\t%s\n" "7. Copy /etc/pacman.conf to TMPDIR/pacman.conf and disable temporarily gpg verification."
   printf "\t%s\n" "8. Download the newest packages which contains the gpg keyrings in TMPDIR"
   printf "\t%s\n" "9. Install temporarily downloaded keyring packages"
   printf "\t%s\n" "10. Remove temporary directory TMPDIR"
   printf "\t%s\n" "11. Switch to a local mirror by Geolocation"
   printf "\t%s\n" "12. Refresh GnuPG Database of pacman from the Internet [optional]"
   printf "\t%s\n" "13. Performing a full upgrade with pacman [optional]"
 
   printf "\n\t%s\n\n" "Note: That tool is not designed to fix gpg issues with your local user GnuPG Database, which is commonly used for AUR Packages as an example."
}
 
HelpUsage () { printf '\e[32m%s\e[0m\n' "$0 [--usage|--help|--basic|--moderate|--aggressive|--ask] (default: [--basic])"; }
 
Menu ()
{
   clear
   while true; do
      printf '\e[33m%s\e[0m\n' "1. Basic"
      printf '\e[33m%s\e[0m\n' "2. Moderate"
      printf '\e[33m%s\e[0m\n' "3. Aggressive"
      printf '\e[33m%s\e[0m\n' "4. Explanations of the methods"
      printf '\n\e[33m%s\e[0m\n\n' "Type [q] to quit."
      PrintQuestion "Choose a Method by typing the number and press ENTER on you keyboard."
      read -p "[1,2,3,4,q]>  " choice
      case $choice in
         1) 
            BasicMethod && exit
         ;;
         2) 
            ModerateMethod && exit
         ;;
         3) 
            AggressiveMethod && exit
         ;;
         4)
            HelpPage && continue
         ;;
         q)
            exit
         ;;
         *)
            clear && PrintError "No valid answer. Continue." && continue ;;
      esac
   done
}
 
[[ -z $@ ]] && BasicMethod && exit
case $1 in 
   --basic)
      BasicMethod && exit
   ;;
   --moderate)
      ModerateMethod && exit
   ;;
   --aggressive)
      AggressiveMethod && exit
   ;;
   --help)
      HelpUsage && HelpPage && exit
   ;;
   --usage)
      HelpUsage && exit
   ;;
   --ask)
      Menu && exit
   ;;
   *)
      PrintError "\"$1\" is not a valid parameter. See \"$0 --usage\""
   ;;
esac

Additional Notes

  • The mirror link provided under notabug.org is no longer accessible. Had to manually create the script locally.
  • My system is pretty up-to-date. Last update was done two weeks ago. Not sure why it would have similar symptom as a “left-behind-system”.
  • My Manjaro distro:
DISTRIB_ID="ManjaroLinux"
DISTRIB_RELEASE="24.0.2"
DISTRIB_CODENAME="Wynsdey"
DISTRIB_DESCRIPTION="Manjaro Linux"

References

HowTo: Work around gpg verification issue on left behind systems

Can’t import keys (Stable Update 2023-07-10)