Skip to content

apt update Blocked: Repository "Changed Its Label Value"

apt update (or Ansible's apt: update_cache) hard-fails and refuses to refresh a repo:

E: Repository 'https://ppa.launchpadcontent.net/ondrej/php/ubuntu noble InRelease' changed its 'Label' value from 'PPA for PHP' to 'Use packages.sury.org/php instead' W: This must be accepted explicitly before updates for this repository can be applied. See apt-secure(8) manpage for details.

Nothing is broken and the packages are unchanged — this is apt's release-info-change protection firing. When a repo's InRelease metadata (Label, Origin, Suite, Codename, Version) changes from the value apt last saw, apt treats it as a potential repo-hijack/mirror-swap and blocks the update until a human accepts the new value once.

Seen on majorlinux (2026-07-05) via the system_update Ansible playbook. Ondrej Surý flipped the ondrej/php Launchpad PPA's Label to nag users toward the official packages.sury.org repo. Only majorlinux tripped it — the other Ubuntu hosts (tttpod, dcaprod, majortoot, teelia) had already refreshed and auto-accepted.

Recurred 2026-07-08 — the PPA Label churned again (Use packages.sury.org/php instead → Use https://packages.sury.org/php/ instead), re-tripping the same block. This is the key lesson: the one-time accept below is not durable against a repo that keeps changing its label. Surý is actively herding PPA users onto sury.org, so the accept must be re-run on every bump — until you leave the PPA entirely (see Real remediation). majorlinux was migrated to sury.org directly on 2026-07-08 and the churn stopped.

Immediate fix — accept the change once

apt-get update --allow-releaseinfo-change

That single run re-syncs the cache and records the new metadata. Every subsequent plain apt update is clean — but only until the value changes again. The accept locks in the label that existed at that instant; if the maintainer keeps churning it (as Surý is doing to push PPA users to sury.org), the next bump re-arms the block and you're back here. If you find yourself running this repeatedly for the same repo, stop patching and migrate off it. Verify:

apt-get update 2>&1 | grep -iE 'changed its|must be accepted' || echo CLEAN
grep -h Label /var/lib/apt/lists/*ondrej*InRelease   # now shows the new value

To accept only a specific field (tighter than the blanket flag):

apt-get update --allow-releaseinfo-change-label      # label only
# also: --allow-releaseinfo-change-{origin,suite,codename,version,defaultpin}

Why the Ansible retries don't help

Ansible's apt module runs plain apt-get update and (in the system_update role) retries on failure. But the release-info block is not transient — every retry hits the same wall and just burns the retry budget before failing the play:

Failed to update apt cache after 5 retries: ... changed its 'Label' value ...

The block only clears once the change is accepted (the command above) or the metadata is refreshed some other way (e.g. unattended-upgrades, which is why the other hosts never failed).

Do NOT globally auto-accept

It's tempting to bake APT::Get::AllowReleaseInfoChange "true"; into /etc/apt/apt.conf.d/ or add --allow-releaseinfo-change to the role for the whole fleet. Don't. That makes every host silently swallow any future repo metadata change — which is exactly the signal this protection exists to surface (a compromised mirror or a repo that's quietly become something else). A one-time manual accept per host, per genuine change, keeps the control meaningful. If recurrence-proofing is truly needed, scope a pre-task to accept changes for that one source only, not fleet-wide.

The label change is Surý telling PPA users to migrate, and the churn won't stop while you stay on the PPA. If the label keeps changing, this is the fix — not repeated accepts. Switch the source to the official packages.sury.org repo, which is the redirect destination: once you point there directly, there's nothing left to redirect you toward, and the block stops recurring.

packages.sury.org/php/dists/ carries a noble suite (and jammy, bookworm, bullseye, trixie), rebuilt daily — Ubuntu is fully supported, not just Debian. The packages are byte-identical to the PPA's (same +deb.sury.org+1 version strings), so it's a transparent source swap with zero package churn.

# Replace the ondrej Launchpad PPA with packages.sury.org (Ubuntu Noble shown)
curl -sSLo /etc/apt/trusted.gpg.d/php.gpg https://packages.sury.org/php/apt.gpg
echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" \
  > /etc/apt/sources.list.d/sury-php.list
mv /etc/apt/sources.list.d/ondrej-ubuntu-php-*.sources /root/  # reversible; or rm
apt-get update            # fresh source = no cached label to compare = no block

Verify the swap is transparent before trusting it:

apt-cache policy php8.4-fpm | grep sury          # candidate now resolves from sury.org
apt-get -s upgrade | grep -E 'upgraded,'         # expect: 0 upgraded, 0 to remove

Done on majorlinux 2026-07-08 after the second label bump — apt update clean, php8.4-fpm resolves from packages.sury.org, apt -s upgrade = 0 changes, PHP-FPM/Apache healthy, site HTTP 200. This matches the existing fleet pattern in dcaprod-lamp.yml / tttpod-lamp.yml, and is codified in majorlinux-lamp.yml.

On the fleet, put the repo swap in the Ansible PHP provisioning path (Sury key → /etc/apt/trusted.gpg.d/php.gpg, apt_repository for deb https://packages.sury.org/php/ noble main) so a rebuild reproduces it, rather than a one-off hand-edit.

Key Notes

  • Metadata change ≠ compromise, usually. Confirm the new value is expected (here, a documented PPA→Sury migration) before accepting. If a repo's Origin/Suite changes for no announced reason, investigate before running the flag.
  • --allow-releaseinfo-change accepts all changed fields for that run; it does not weaken future checks — the next unexpected change still blocks.
  • Distinct from stale .distUpgrade quarantine files (a release-upgrade artifact), which is a different apt breakage — see the majorlinux 2026-04-28 cleanup.