Cyril Brulebois <[email protected]> (2026-07-17): > - upgrade output: > > Preparing to unpack .../ca-certificates_20250419_all.deb ... > Unpacking ca-certificates (20250419) over (20230311+deb12u1) ... > Preparing to unpack .../ca-certificates-java_20240118_all.deb ... > Unpacking ca-certificates-java (20240118) over (20230710~deb12u1) ... > Setting up ca-certificates (20250419) ... > Updating certificates in /etc/ssl/certs... > rehash: warning: skipping ca-certificates.crt,it does not contain exactly > one certificate or CRL > 21 added, 13 removed; done. > Setting up ca-certificates-java (20240118) ... > done. > Processing triggers for ca-certificates (20250419) ... > Updating certificates in /etc/ssl/certs... > 0 added, 0 removed; done. > Running hooks in /etc/ca-certificates/update.d... > done. > Processing triggers for ca-certificates-java (20240118) ... > done. […]
> I haven't tried to understand exactly what's happening here yet, the
> levels of indirection are a little intimidating…
Initial investigation
=====================
- postinst enables “fresh” on initial installation and also when
upgrading from specific, very old versions; that's definitely not the
case here.
- update-ca-certificates isn't called with --fresh during the upgrade;
- therefore I'm quite certain there's no chance to enter the first
“then” of this block:
https://sources.debian.org/src/ca-certificates-java/20240118/debian/ca-certificates-java.postinst#L119-L123
- in the context of an upgrade, it would make sense to go through a
to-do list left behind by the hook, which would be the “pending” file
as I understand it, and that'd go through the second “then” of the
aforementioned block.
Now, I don't have any definitive proof yet, but seeing how the upgrade
output gives two update runs (cherry-picking lines from the log above):
Updating certificates in /etc/ssl/certs...
21 added, 13 removed; done.
[…]
Updating certificates in /etc/ssl/certs...
0 added, 0 removed; done.
for a single hook run, after the second update run:
Running hooks in /etc/ca-certificates/update.d...
It seems safe to assume this hook run doesn't see any changes, and
leaves an empty (or maybe missing) “pending” file. If that hook had run
twice, the first run might have generated an interesting “pending” file
(with the additions/deletions), while the second one would have been a
no-op (the hook uses >> to append to the pending file, it doesn't start
from scratch, so a second hook run wouldn't reset what was generated by
the first one).
Redoing the upgrade under strace confirms we go through all of the
update_certs() function twice, with the hook running in-between,
creating an empty “pending” file via:
cat - >> /var/lib/ca-certificates-java/pending
which is confirmed by the very few syscalls performed by PID 74084 (not
pictured below), and by st_size=0 on the last newfstatat() call:
73273 newfstatat(AT_FDCWD,
"/var/lib/ca-certificates-java/convert_pkcs12_keystore_to_jks", 0x7ffdf65011b0,
0) = -1 ENOENT (No such file or directory)
73273 newfstatat(AT_FDCWD, "/var/lib/ca-certificates-java/fresh",
0x7ffdf6501200, 0) = -1 ENOENT (No such file or directory)
73273 newfstatat(AT_FDCWD, "/var/lib/ca-certificates-java/fresh",
0x7ffdf6501250, 0) = -1 ENOENT (No such file or directory)
73273 newfstatat(AT_FDCWD, "/var/lib/ca-certificates-java/pending",
0x7ffdf6501200, 0) = -1 ENOENT (No such file or directory)
73297 newfstatat(AT_FDCWD, "/var/lib/ca-certificates-java/fresh",
0x55e4ea327c70, AT_SYMLINK_NOFOLLOW) = -1 ENOENT (No such file or directory)
73298 newfstatat(AT_FDCWD, "/var/lib/ca-certificates-java/pending",
0x562f3f97fc70, AT_SYMLINK_NOFOLLOW) = -1 ENOENT (No such file or directory)
74081 openat(AT_FDCWD, "/var/lib/ca-certificates-java/pending",
O_WRONLY|O_CREAT|O_APPEND, 0666) = 3
74081 fcntl(1, F_DUPFD, 10) = 11
74081 close(1) = 0
74081 fcntl(11, F_SETFD, FD_CLOEXEC) = 0
74081 dup2(3, 1) = 1
74081 close(3) = 0
[…]
74084 execve("/usr/bin/cat", ["cat", "-"] […]
74089 newfstatat(AT_FDCWD,
"/var/lib/ca-certificates-java/convert_pkcs12_keystore_to_jks", 0x7ffe43dfba90,
0) = -1 ENOENT (No such file or directory)
74089 newfstatat(AT_FDCWD, "/var/lib/ca-certificates-java/fresh",
0x7ffe43dfbae0, 0) = -1 ENOENT (No such file or directory)
74089 newfstatat(AT_FDCWD, "/var/lib/ca-certificates-java/fresh",
0x7ffe43dfbb30, 0) = -1 ENOENT (No such file or directory)
74089 newfstatat(AT_FDCWD, "/var/lib/ca-certificates-java/pending",
{st_dev=makedev(0xfd, 0x1), st_ino=2363271, st_mode=S_IFREG|0644, st_nlink=1,
st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=0,
st_atime=1784260504 /* 2026-07-17T05:55:04.578209913+0200 */,
st_atime_nsec=578209913, st_mtime=1784260504 /*
2026-07-17T05:55:04.578209913+0200 */, st_mtime_nsec=578209913,
st_ctime=1784260504 /* 2026-07-17T05:55:04.578209913+0200 */,
st_ctime_nsec=578209913}, 0) = 0
https://sources.debian.org/src/ca-certificates-java/20240118/debian/ca-certificates-java.postinst#L62-L128
All of this confirms why we end up with a no-op regarding the cacerts
file.
I'm not sure what a fix would look like. Running hooks after each update
might be risky, because it could lead to trigger cycles or something?
Possible workaround
===================
In the meanwhile, `update-ca-certificates --fresh` might be tempting,
but it's not sufficient: it only ensures all current certificates get
added to cacerts, it doesn't reflect deletions. Removing the cacerts
file beforehands makes it possible to finally get in sync with what a
fresh trixie system looks like:
rm -f /etc/ssl/certs/java/cacerts
update-ca-certificates --fresh
The 13 deletions, resulting in 149 entries total:
-debian:autoridad_de_certificacion_firmaprofesional_cif_a62634068_2.pem,
Jul 17, 2026, trustedCertEntry,
-debian:entrust_root_certification_authority_-_g4.pem, Jul 17, 2026,
trustedCertEntry,
-debian:e-tugra_certification_authority.pem, Jul 17, 2026,
trustedCertEntry,
-debian:e-tugra_global_root_ca_ecc_v3.pem, Jul 17, 2026, trustedCertEntry,
-debian:e-tugra_global_root_ca_rsa_v3.pem, Jul 17, 2026, trustedCertEntry,
-debian:hongkong_post_root_ca_1.pem, Jul 17, 2026, trustedCertEntry,
-debian:securesign_rootca11.pem, Jul 17, 2026, trustedCertEntry,
-debian:security_communication_rootca3.pem, Jul 17, 2026, trustedCertEntry,
-debian:security_communication_root_ca.pem, Jul 17, 2026, trustedCertEntry,
-debian:swisssign_silver_ca_-_g2.pem, Jul 17, 2026, trustedCertEntry,
-debian:trustcor_eca-1.pem, Jul 17, 2026, trustedCertEntry,
-debian:trustcor_rootcert_ca-1.pem, Jul 17, 2026, trustedCertEntry,
-debian:trustcor_rootcert_ca-2.pem, Jul 17, 2026, trustedCertEntry,
(out of 150 because of some encoding fun, but that's another story:
/etc/ssl/certs/NetLock_Arany_=Class_Gold=_F?tan?s?tv?ny.pem)
Cheers,
--
Cyril Brulebois -- Debian Consultant @ DEBAMAX -- https://debamax.com/
signature.asc
Description: PGP signature
__ This is the maintainer address of Debian's Java team <https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/pkg-java-maintainers>. Please use [email protected] for discussions and questions.
