SSD Nodes Learn Hosting plans →
Hướng dẫn Matt ConnorBởi Matt Connor · Cập nhật ngày 2026-08-22

Sửa lỗi apt sources bị khai báo nhiều lần

Gặp lỗi "Target is configured multiple times" khi apt update? Tìm cặp file .list và .sources trùng repository, giữ một file để update sạch.

Ý nghĩa của lỗi trùng apt sources

apt sources bị trùng nghĩa là một repository được khai báo hai lần trong hai file khác nhau và APT (advanced package tool) đã tìm thấy cả hai bản khai báo. Trên Ubuntu 24.04 trở lên, lỗi này gần như luôn xảy ra vì một third-party install script đã ghi một file one-line .list cũ trong khi file deb822 .sources cho cùng repository đã có sẵn trên máy. Không có gì bị hỏng và không package nào gặp rủi ro. Xóa một trong hai bản khai báo là thông báo sẽ biến mất.

Đây là dòng mà mọi người thường dán vào ô tìm kiếm:

W: Target Packages (stable/binary-amd64/Packages) is configured multiple times in /etc/apt/sources.list.d/docker.list:1 and /etc/apt/sources.list.d/docker.sources:1

Đọc từ cuối dòng lên. Hai file, mỗi file có số dòng, khai báo cùng một nội dung. Target Packages là index mà apt tải xuống để biết một repository cung cấp những package nào, còn stable/binary-amd64/Packages chỉ component (stable) và architecture (amd64) mà index đó áp dụng. Vì vậy, apt đang báo rằng index amd64 cho component stable được cấu hình trong docker.list ở dòng 1, rồi lại được cấu hình trong docker.sources ở dòng 1.

Trên apt 3.0 trở lên, tức Ubuntu 25.04 trở đi và Debian 13, thông báo tương tự bắt đầu bằng Warning: thay vì W:. Phần văn bản sau prefix không thay đổi.

Cảnh báo này là trường hợp nhẹ. apt gộp hai bản khai báo và lệnh update vẫn chạy vì cả hai mô tả cùng một archive với cùng một key. Trường hợp nghiêm trọng sẽ dừng toàn bộ quá trình:

E: Conflicting values set for option Signed-By regarding source https://download.docker.com/linux/ubuntu/ noble: /usr/share/keyrings/docker-archive-keyring.gpg != /etc/apt/keyrings/docker.asc
E: The list of sources could not be read.

apt từ chối xử lý trong trường hợp này vì hai bản khai báo chỉ các signing key khác nhau cho cùng một archive. apt sẽ gộp hai bản khai báo giống hệt nhau, nhưng sẽ không chọn giữa hai giá trị Signed-By vì chọn nhầm nghĩa là kiểm tra chữ ký package bằng một key mà chủ archive chưa từng dùng để ký. Vì vậy, apt không đọc bất kỳ source nào. apt update và apt install đều thất bại với đúng hai dòng đó cho đến khi bạn sửa các file thủ công.

Cách tạo ra mục trùng lặp

Hai định dạng nằm trong các file riêng với phần mở rộng khác nhau, nên không có gì trên đĩa ngăn cả hai cùng tồn tại. apt chỉ phát hiện phần chồng lấp khá muộn, khi mở rộng từng file source thành danh sách các target index mà nó dự định tải xuống. Trước thời điểm đó, docker.list và docker.sources là hai file không liên quan.

Bốn sự kiện thông thường có thể tạo ra cặp này:

  • Một script cài đặt của vendor hoặc một command được sao chép từ bài viết cũ ghi /etc/apt/sources.list.d/vendor.list với một dòng tee.
  • Sau đó package của chính vendor phát hành /etc/apt/sources.list.d/vendor.sources và tự cài file này cho bạn.
  • add-apt-repository trên Ubuntu 24.04 trở lên ghi các file .sources theo định dạng deb822, nên một PPA (personal package archive) mà trước đây bạn thêm thủ công dưới dạng .list sẽ xuất hiện lại dưới dạng .sources.
  • Một lần nâng cấp release đã chuyển các source riêng của distribution sang deb822 nhưng để nguyên file .list bạn tự viết bên cạnh chúng.

Mỗi đường dẫn đều hợp lý nếu xét riêng. Mục trùng lặp xuất hiện khi hai đường dẫn xảy ra trên cùng một máy, thường cách nhau vài tháng.

Hai định dạng, đặt cạnh nhau

Định dạng cũ dùng một dòng cho mỗi repository, và mọi thành phần đều được xác định theo vị trí.

deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu noble stable

Thứ tự là cố định: loại repository (`deb cho binary package, deb-src` cho source package), tiếp theo là các option trong ngoặc vuông, URI (uniform resource identifier) của archive, suite, rồi một hoặc nhiều component. Vì ý nghĩa phụ thuộc vào vị trí, chỉ cần đặt sai một dấu cách là apt sẽ đọc khác đi.

deb822 biểu diễn cùng thông tin dưới dạng một stanza gồm các field có tên. Tên này bắt nguồn từ RFC 822, kiểu header của mail mà Debian đã dùng cho các control file của package.

Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: noble
Components: stable
Architectures: amd64
Signed-By: /etc/apt/keyrings/docker.asc

Cùng repository, cùng key, không thêm gì. Việc ánh xạ rất trực tiếp: `deb trở thành Types, địa chỉ archive trở thành URIs, suite trở thành Suites, các component trở thành Components, và mỗi option trong ngoặc vuông trở thành một field riêng. Vì vậy, signed-by= trở thành Signed-By: và arch= trở thành Architectures:`.

Tên mọi field đều ở dạng số nhiều vì mỗi field nhận một danh sách cách nhau bằng dấu cách. `Suites: noble noble-updates noble-backports trong một stanza thay thế cho 3 dòng deb riêng biệt. Một dòng trống kết thúc một stanza, nên một file .sources có thể chứa nhiều repository. deb822 cũng hỗ trợ những thiết lập mà định dạng một dòng xử lý không tốt: Enabled: no để tắt repository, Trusted, Check-Valid-Until, và một key inline được dán trực tiếp vào Signed-By`, trong đó mỗi dòng được thụt vào 1 dấu cách và các dòng trống được ghi bằng một dấu chấm đơn.

Vị trí của từng file

  • /etc/apt/sources.list: file đơn ban đầu. Trên Ubuntu 24.04 trở lên, file này thường trống hoặc chỉ chứa comment trỏ đến vị trí mới.
  • /etc/apt/sources.list.d/*.list: các entry một dòng, thường mỗi repository dùng một file.
  • /etc/apt/sources.list.d/*.sources: các stanza deb822. Ubuntu 24.04 trở lên lưu các repository riêng của distribution tại đây, trong ubuntu.sources.
  • /etc/apt/keyrings/: nơi lưu các key bạn thêm vào. /usr/share/keyrings/ chứa các key đến từ một package.

apt chỉ đọc các file có tên kết thúc bằng .list hoặc .sources. Tên file có thể chứa chữ cái, chữ số, dấu gạch dưới, dấu gạch ngang và dấu chấm. File có extension khác sẽ bị bỏ qua kèm thông báo. Điều này quan trọng đối với cách khắc phục bên dưới.

Tìm cặp bị trùng

Bắt đầu bằng cách liệt kê thư mục:

ls -l /etc/apt/sources.list.d/
-rw-r--r-- 1 root root  195 Aug  3 09:12 docker.list
-rw-r--r-- 1 root root  254 Aug  9 14:40 docker.sources
-rw-r--r-- 1 root root 2683 Jun 11 08:02 ubuntu.sources

Hai file có cùng tên gốc nhưng khác phần mở rộng thường là cặp bị trùng, nhưng không được tin hoàn toàn vào tên file. Hãy đọc nội dung, vì file trùng có thể mang bất kỳ tên nào:

grep -rn -E '^(deb |deb-src |Types:|URIs:|Suites:|Signed-By:)' /etc/apt/sources.list /etc/apt/sources.list.d/
/etc/apt/sources.list.d/docker.list:1:deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu noble stable
/etc/apt/sources.list.d/docker.sources:1:Types: deb
/etc/apt/sources.list.d/docker.sources:2:URIs: https://download.docker.com/linux/ubuntu
/etc/apt/sources.list.d/docker.sources:3:Suites: noble
/etc/apt/sources.list.d/docker.sources:6:Signed-By: /etc/apt/keyrings/docker.asc

Cặp bị trùng là 2 mục có cùng host và cùng suite. Cả 2 đều trỏ đến https://download.docker.com/linux/ubuntu và suite noble, nên chúng là cùng một repository được khai báo 2 lần. Các đường dẫn Signed-By của chúng cũng khác nhau. Đây là nguyên nhân tạo ra lỗi Conflicting values đã hiển thị ở trên.

Dùng grep thay vì lệnh apt cho bước này. Khi apt đã dừng vì xung đột, nó cũng không thể liệt kê các source của bạn. Vì vậy, apt-cache policy sẽ in lại cùng lỗi đó thay vì đưa ra kết quả bạn cần.

Sửa theo cách này: giữ file deb822, bỏ file cũ

Giữ file .sources. Đây là định dạng mà các công cụ apt hiện ghi ra, và Debian lẫn Ubuntu đều đang chuyển sang định dạng này. Trước khi xóa bất kỳ thứ gì, hãy kiểm tra xem path nào trong 2 path chính đang tồn tại trên disk:

ls -l /etc/apt/keyrings/ /usr/share/keyrings/ | grep -i docker
-rw-r--r-- 1 root root 4813 Aug  9 14:40 docker.asc

Chỉ có /etc/apt/keyrings/docker.asc tồn tại, nên file deb822 mới là file phản ánh đúng cấu hình. File .list đang trỏ đến một key đã bị xóa. Nếu file bạn định giữ lại trỏ đến key bị thiếu, trước tiên hãy chép path đang hoạt động vào file đó, rồi xóa file còn lại.

Hãy chuyển file cũ ra khỏi directory thay vì xóa hẳn:

sudo mkdir -p /root/apt-sources-backup
sudo mv /etc/apt/sources.list.d/docker.list /root/apt-sources-backup/
sudo apt update

Đổi tên file thành docker.list.bak và giữ nguyên trong directory cũng được vì apt bỏ qua các extension không nhận diện. Tuy nhiên, mỗi lần apt chạy sẽ in ra thông báo này:

N: Ignoring file 'docker.list.bak' in directory '/etc/apt/sources.list.d/' as it has an invalid filename extension

Chuyển file sang nơi khác sẽ không còn thông báo đó trên màn hình, đồng thời vẫn giữ được bản backup. Sau đó, apt update ở trạng thái đúng sẽ có dạng như sau, không có dòng nào khai báo 2 file:

Hit:1 http://archive.ubuntu.com/ubuntu noble InRelease
Get:2 https://download.docker.com/linux/ubuntu noble InRelease [48.8 kB]
Get:3 http://security.ubuntu.com/ubuntu noble-security InRelease [126 kB]
Fetched 175 kB in 1s (146 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.

Bây giờ xác nhận repository vẫn hoạt động sau khi chỉnh sửa:

apt-cache policy | grep download.docker.com
 500 https://download.docker.com/linux/ubuntu noble/stable amd64 Packages
     origin download.docker.com

Nếu tài liệu của vendor vẫn giả định dùng file một dòng, bạn có thể giữ file đó và xóa file .sources thay thế. Quy tắc quyết định trong cả 2 trường hợp là: mỗi archive và suite cụ thể chỉ được một file khai báo.

Vì sao một source bên thứ ba bị lỗi làm apt update không chạy được

Lỗi gần kề có vẻ khác nhưng cùng một nguyên nhân: một source bên thứ ba mà apt không thể sử dụng. Trường hợp đầu tiên là thiếu key:

Err:5 https://download.docker.com/linux/ubuntu noble InRelease
  The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 7EA0A9C3F273FCD8
E: The repository 'https://download.docker.com/linux/ubuntu noble InRelease' is not signed.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.

Trường Signed-By bị thiếu hoặc trỏ đến một file không chứa key hợp lệ. Vì vậy, apt không thể xác minh chữ ký trên file InRelease của archive. apt sẽ loại bỏ toàn bộ repository đó thay vì tin các package list mà nó không thể kiểm tra. Hãy kiểm tra chính file key:

ls -l /etc/apt/keyrings/docker.asc
gpg --show-keys /etc/apt/keyrings/docker.asc

Key hợp lệ sẽ in ra dòng pub chứa key id và dòng uid ghi tên vendor. gpg: no valid OpenPGP data found. nghĩa là file đó không phải key. Nguyên nhân thường là quá trình download đã lưu một trang lỗi vì URL của key đã thay đổi. Hãy tải lại key, kiểm tra file, rồi chạy apt update.

Trường hợp thứ hai xuất hiện sau khi nâng cấp release:

Err:6 https://ppa.launchpadcontent.net/ondrej/php/ubuntu plucky InRelease
  404  Not Found [IP: 10.0.0.80 443]
E: The repository 'https://ppa.launchpadcontent.net/ondrej/php/ubuntu plucky Release' does not have a Release file.

PPA chưa publish gì cho suite đó. Vì vậy, path này không tồn tại trên server và request trả về lỗi 404. Các repository khác của bạn vẫn update bình thường, còn những package đã cài vẫn không bị ảnh hưởng. Tuy nhiên, lần chạy này kết thúc với mã khác 0. Vì thế, mọi script kiểm tra exit status của apt update sẽ báo lỗi mỗi lần chạy. Đây là lý do nên xóa source đã chết trên máy đang cấu hình unattended security upgrades: các cảnh báo lặp lại hằng ngày có thể che khuất một lỗi thật sự. Các script cài đặt của vendor gặp cả hai trường hợp này. Vì vậy, phần lớn lỗi cài đặt Tailscale trên Ubuntu thực chất là do script không ghi keyring hoặc archive không có release codename đó.

Tắt một source mà không làm hỏng các source khác

Với file deb822, thêm một field vào stanza rồi lưu lại:

Types: deb
URIs: https://ppa.launchpadcontent.net/ondrej/php/ubuntu
Suites: plucky
Components: main
Signed-By: /etc/apt/keyrings/ondrej-php.asc
Enabled: no

apt manual khuyến nghị cách này thay vì comment từng dòng trong stanza, và việc hoàn tác cũng dễ hơn. Với file một dòng, thêm # vào đầu dòng. Với cả hai định dạng, bạn cũng có thể chuyển file ra khỏi /etc/apt/sources.list.d/. Hãy chọn cách này khi repository đã bị gỡ vĩnh viễn.

Chạy lại sudo apt update. Block Err: của repository đó sẽ biến mất và exit status trở về 0. Bạn có thể kiểm tra bằng echo $? ở dòng tiếp theo.

Không bao giờ sửa một source bị hỏng bằng sudo rm /etc/apt/sources.list.d/*. Trên Ubuntu 24.04 trở lên, lệnh này xóa ubuntu.sources. File này chứa các repository của chính distribution, khiến apt không còn package list nào và báo E: Unable to locate package curl cho phần mềm rõ ràng đang tồn tại. Nếu đã chạy lệnh đó, hãy ghi lại file:

Types: deb
URIs: http://archive.ubuntu.com/ubuntu/
Suites: noble noble-updates noble-backports
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

Types: deb
URIs: http://security.ubuntu.com/ubuntu/
Suites: noble-security
Components: main restricted universe multiverse
Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg

Lưu file đó thành /etc/apt/sources.list.d/ubuntu.sources, thay noble bằng tên release của bạn lấy từ lsb_release -cs, rồi chạy sudo apt update.

Chuyển các file .list cũ sang deb822

Từ tháng 8 năm 2026, apt 3.0 trở lên có sẵn công cụ chuyển đổi cho việc này. Debian 13 có công cụ này. Ubuntu 25.04 và mọi bản phát hành sau đó, bao gồm 26.04, cũng có. Kiểm tra phiên bản, rồi chạy:

apt --version
sudo apt modernize-sources

Lệnh này viết lại các file một dòng trong /etc/apt/sources.list.d/ thành các file deb822 .sources. Đọc nội dung lệnh in ra, sau đó tự liệt kê thư mục và chạy apt update trước khi tin tưởng kết quả. Ubuntu 24.04 đi kèm apt cũ hơn, không có subcommand này. Trên bản đó, lệnh trả về E: Invalid operation modernize-sources. Với bản phát hành này, hãy chuyển đổi thủ công theo bảng ánh xạ field ở trên.

Hiện tại, việc chuyển đổi là tùy chọn vì apt vẫn đọc được cả hai định dạng. Tuy nhiên, nên thực hiện trên server bạn dự định tiếp tục sử dụng, vì mọi tool ghi sources hiện đều ghi theo định dạng deb822. Một máy chỉ có các file .sources sẽ không thể phát sinh loại bản sao trùng lặp này.

Giữ các source bên thứ ba gọn gàng trên server

Các repository bên thứ ba là phần xuống cấp nhanh nhất trên server. Mỗi repository là cam kết của một bên khác rằng họ sẽ tiếp tục phát hành package cho bản Ubuntu của bạn. Mỗi lần nâng cấp release sẽ kiểm tra tất cả các cam kết đó cùng lúc.

  • Chỉ thêm repository bên thứ ba khi package của distribution không đáp ứng được yêu cầu. Một LAMP stack thông thường trên Ubuntu 24.04 không cần repository nào: Ubuntu archive đã có mọi package mà stack này sử dụng, kèm security update trong suốt vòng đời của release.
  • Lưu key trong /etc/apt/keyrings/, mỗi vendor một file, mode 644. User không đặc quyền _apt thực hiện việc tải xuống và phải đọc được key. Vì vậy, file key chỉ root đọc được sẽ gây lỗi permission mỗi khi fetch từ repository đó.
  • Trỏ Signed-By đến đúng file đó trong mọi stanza. Một key nằm trong /etc/apt/trusted.gpg hoặc /etc/apt/trusted.gpg.d/ sẽ được tin cậy cho mọi repository trên máy. Điều này có nghĩa là vendor key được thêm từ nhiều năm trước có thể xác thực package từ bất kỳ nguồn nào.
  • Trước khi nâng cấp release, hãy đọc các source và kiểm tra xem từng vendor đã publish cho suite mà bạn sắp chuyển sang chưa.

Một key trong keyring global cũ sẽ xuất hiện trong mỗi lần update:

W: https://download.docker.com/linux/ubuntu/dists/noble/InRelease: Key is stored in legacy trusted.gpg keyring (/etc/apt/trusted.gpg), see the DEPRECATION section in apt-key(8) for details.

Export riêng key đó thành một file, rồi trỏ stanza đến file này:

gpg --no-default-keyring --keyring /etc/apt/trusted.gpg --export 7EA0A9C3F273FCD8 | sudo tee /etc/apt/keyrings/docker.gpg > /dev/null
sudo chmod 644 /etc/apt/keyrings/docker.gpg

Thêm Signed-By: /etc/apt/keyrings/docker.gpg vào stanza của repository và chạy sudo apt update. Cảnh báo sẽ dừng khi không còn repository nào phụ thuộc vào keyring cũ. Sau đó bạn có thể xóa entry bằng sudo gpg --no-default-keyring --keyring /etc/apt/trusted.gpg --delete-key 7EA0A9C3F273FCD8.

Có thêm một thói quen giúp tránh phần lớn sự cố. do-release-upgrade vô hiệu hóa các source bên thứ ba trong quá trình nâng cấp và tiếp tục để chúng ở trạng thái tắt sau đó. Việc bật lại thủ công từng source một chính là lúc các khai báo trùng lặp thường được tạo ra. Hãy đọc hướng dẫn nâng cấp Ubuntu 24.04 lên 26.04 trước khi bắt đầu và ghi lại những repository bạn vẫn cần. Trên một máy vừa được dựng xong, thời điểm ít tốn công nhất để cấu hình source đúng là trong 10 phút đầu tiên trên VPS mới, khi các entry duy nhất trên máy vẫn là những entry Ubuntu đã ship.

FAQ

Vì sao apt báo một target được cấu hình nhiều lần?

Vì có hai file trong /etc/apt/sources.list.d/ khai báo cùng repository, suite và component. Thông báo chỉ rõ cả hai file cùng số dòng, chẳng hạn docker.list:1 và docker.sources:1. apt gộp chúng rồi tiếp tục, nên thao tác update vẫn hoạt động. Tuy vậy, bạn vẫn nên xóa bản trùng: nếu hai file chỉ định các signing key khác nhau, apt sẽ dừng với E: Conflicting values set for option Signed-By và từ chối đọc toàn bộ source, đồng thời chặn cả apt install.

Tôi nên giữ file .list hay file .sources?

Giữ file .sources. deb822 là định dạng mà add-apt-repository ghi trên Ubuntu 24.04 trở lên. Định dạng này dùng một field có tên cho mỗi thiết lập thay vì văn bản theo vị trí trong dấu ngoặc vuông, và đây là hướng mà các bản phân phối đang chuyển sang. Trước khi xóa file .list, hãy xác nhận path Signed-By bên trong file .sources trỏ đến một key đang tồn tại bằng ls -l /etc/apt/keyrings/. Hãy chuyển file cũ ra khỏi /etc/apt/sources.list.d/ thay vì đổi tên nó ngay trong thư mục, vì tên .bak còn sót lại sẽ khiến apt in thông báo bỏ qua file ở mỗi lần chạy.

Làm thế nào để tắt một repository apt mà không xóa nó?

Trong file deb822 .sources, thêm Enabled: no vào stanza. Trong file .list một dòng, đặt # ở đầu dòng. Dù dùng cách nào, hãy chạy sudo apt update sau đó. Khi ấy, Err: block của repository đó sẽ biến mất. Đây là cách phù hợp khi một repository bên thứ ba chưa có package cho release Ubuntu của bạn và lỗi 404 của nó khiến apt update thoát với mã khác 0.

Định dạng sources.list một dòng có bị loại bỏ không?

Định dạng này đã deprecated nhưng chưa bị xóa. apt vẫn đọc các file .list và sẽ tiếp tục hỗ trợ trong thời gian dài, nên server của bạn không bị hỏng ngay ngày mai. Tool mới ghi theo deb822: Ubuntu 24.04 trở lên lưu các repository của distribution trong /etc/apt/sources.list.d/ubuntu.sources, còn add-apt-repository ghi các file .sources. Trên apt 3.0 trở lên, sudo apt modernize-sources chuyển đổi các file mà bạn vẫn còn.

#apt#ubuntu#deb822#package-management#troubleshooting