Dear Maintainer,
With OpenSSL configured in FIPS-only mode (only the "base" and "fips"
providers
active; the "default" provider disabled), "apt-get update"/"install"
against an
HTTPS repository intermittently fails with:
Err:N https://...repo...
OpenSSL error: error:0308010C:digital envelope routines::unsupported
Error reading from server - read (5: Input/output error)
Root cause
----------
During the TLS handshake, libssl performs an implicit EVP_MD_fetch() for the
legacy MD5 / MD5-SHA1 digests (used for pre-TLS-1.2 handshake signing and
the
TLS 1.0/1.1 PRF). Under a FIPS-only provider configuration those digests are
unavailable (they exist only in the default provider), so the fetch fails
and
leaves "error:0308010C ... unsupported" on the thread's OpenSSL error queue.
This is benign: the handshake completes fine. "openssl s_client" to the same
host under the identical FIPS config connects successfully with the very
same
failed MD5/MD5-SHA1 fetches (verifiable with an LD_PRELOAD trace of
EVP_MD_fetch).
The actual failure is that apt does not clear the OpenSSL error queue
before its
TLS I/O. In methods/connect.cc, TlsFd::Read() and TlsFd::Write() call
SSL_read()/SSL_write() and then HandleError() -> SSL_get_error() WITHOUT a
preceding ERR_clear_error(). When SSL_read() later returns <= 0 for a benign
reason, SSL_get_error() consults the non-empty error queue, returns
SSL_ERROR_SSL, and apt reports the stale MD5 error as a fatal read failure
(errno = EIO -> "Error reading from server").
This violates the documented precondition in SSL_get_error(3): "The current
thread's error queue must be empty before the TLS/SSL I/O operation is
attempted, [...] as the SSL_get_error() function uses the error queue
[...]."
PostgreSQL fixed the identical class of bug (stale FIPS-mode error-queue
entry
misreported later) by calling ERR_clear_error() "on the way in"; libpq
already
does this around its OpenSSL I/O.
This did not occur before Debian 13 / apt 3.0: apt 2.6 (bookworm) used
GnuTLS
for its TLS transport, which does not touch OpenSSL's providers or error
queue.
Reproduction (Debian 13)
------------------------------
Minimal, self-contained Dockerfile. The build itself fails at the final RUN
(installing Docker from an HTTPS repo) -- "docker build ." is the whole
repro:
FROM debian:13-slim
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
# FIPS-only OpenSSL: install the FIPS provider, then activate base +
fips and
# disable the default provider.
RUN apt-get update --yes \
&& apt-get install --yes --no-install-recommends \
ca-certificates openssl openssl-provider-fips \
&& MODULES_DIR="$(openssl version -m | cut -d'"' -f2)" \
&& openssl fipsinstall -out /etc/ssl/fipsmodule.cnf -module
"${MODULES_DIR}/fips.so"
RUN sed -i 's|^#\s*\.include\s\+fipsmodule.cnf|.include
/etc/ssl/fipsmodule.cnf|' /etc/ssl/openssl.cnf \
&& sed -i 's/^default\s*=\s*default_sect/# default = default_sect/'
/etc/ssl/openssl.cnf \
&& sed -i 's/^#\s*fips\s*=\s*fips_sect/fips = fips_sect\nbase =
base_sect\n\n[base_sect]\nactivate = 1/' /etc/ssl/openssl.cnf
# ("openssl list -providers" now shows only base + fips.)
# Install Docker from its official HTTPS apt repo (any HTTPS repo
triggers it;
# this is just a convenient public one). This RUN fails:
# OpenSSL error: error:0308010C ... Error reading from server
# E: Package 'docker-ce' has no installation candidate
RUN apt-get install --no-install-recommends -y ca-certificates curl
gnupg \
&& install -m 0755 -d /etc/apt/keyrings \
&& curl -fsSL https://download.docker.com/linux/debian/gpg | gpg
--dearmor -o /etc/apt/keyrings/docker.gpg \
&& echo "deb [signed-by=/etc/apt/keyrings/docker.gpg]
https://download.docker.com/linux/debian trixie stable" \
> /etc/apt/sources.list.d/docker.list \
&& apt-get update \
&& apt-get install --no-install-recommends -y docker-ce docker-ce-cli
containerd.io
Build it:
docker build .
The build fails at the final RUN with the error:0308010C / "Error reading
from
server" message above. (The underlying trigger is a read returning <= 0
while
the stale error is queued, so in principle a fluke pass is possible; in
practice
fetching the Docker repo over HTTPS this way fails on essentially every
build,
matching what we see in CI. If a build does pass, rebuild with --no-cache.)
For contrast, the connection itself is fine and the failed MD5 fetch is
benign --
both of these succeed under the identical FIPS config:
# same handshake, succeeds, proving MD5 is not actually needed:
openssl s_client -connect download.docker.com:443 -servername
download.docker.com </dev/null
# and apt works if the default provider is made available:
OPENSSL_CONF=/dev/null apt-get update # (with the docker.list
source above)
System information
------------------
Debian release: 13 (trixie), amd64
Versions of relevant packages:
apt 3.0.3
libssl3t64 3.5.6-1~deb13u2 (OpenSSL; apt's TLS backend in 3.0)
openssl 3.5.6-1~deb13u2
libc6 2.41-12+deb13u3
Reproduced in a stock debian:13-slim container (see Dockerfile above).
Suggested fix
-------------
Clear the OpenSSL error queue immediately before each
SSL_read()/SSL_write() in
methods/connect.cc, mirroring libpq:
ssize_t Read(void *buf, size_t count) override {
assert(ssl);
+ ERR_clear_error();
return HandleError(SSL_read(ssl, buf, count));
}
ssize_t Write(void *buf, size_t count) override {
assert(ssl);
+ ERR_clear_error();
return HandleError(SSL_write(ssl, buf, count));
}
This makes apt robust to any benign leftover OpenSSL error, not just the
FIPS/MD5 case.
Michael Hamill
Senior Software Engineer II
michael.hamill@wellhive.com
www.wellhive.com
WELLHIVE CONFIDENTIALITY NOTICE: The contents of this email message and any attachments are intended solely for the addressee(s). Unless otherwise indicated, it contains information that is confidential, privileged and/or exempt from disclosure under applicable law. If you are not the named addressee, you are not authorized to read, print, retain, copy or disseminate this message or any part of it. If you have received this message in error, please notify the sender immediately by e-mail and delete all copies of the message.
Control: reassign -1 openssl Thanks for your bug report. This seems to be a bug in OpenSSL, and the proposed workaround is wholly inappropriate. This also points out there is _another_ bug somewhere, as we _should_ have raised this error _before_ we enter the Read/Write functions. You'll find you often need to patch OpenSSL to use it in a FIPS setting, and relying on the packaged version is insufficient. Thanks!
Is this a technical profound statement? If so based on what? As someone who maintains the package in question I am curious what I or upstream could do. Sebastian
control: forwarded -1 https://github.com/openssl/openssl/issues/31624
Control: reassign -1 apt 3.0.3 https://github.com/openssl/openssl/issues/31624 There is: | The correct fix is for the application (apt in this case), to do what | postgresql did, and call ERR_clear_error(), prior to a subsequent SSL | call. and | I want to add one nuance after checking the source code of 3.5: I'm not | convinced that upstream libssl 3.5.6 is the source of the stale | MD5/MD5-SHA1 error described here. In the code, the optional digest | fetch helper ssl_evp_md_fetch uses ERR_set_mark / ERR_pop_to_mark, and | the sigalg probing code is also protected. | | Apt source code also uses OpenSSL EVP digest code outside the TLS path, | including MD5 hashing, so there may be more than one possible source of | a stale FIPS/provider error before the later TLS I/O.  Sebastian
That is not a fix and not acceptable. We must not ignore random errors. I will not accept quick hacks that can fundamentally break security. PostgreSQL's work around is a potential security issue and should be treated as such. It is not acceptable in production code to silently discard the error queue, errors need to be raised at the appropriate point in time (or discarded - with safety checks - at the appropriate point in time). We should treat this as a release critical bug in postgresql tbh. Right so the error is that the context is not correctly cleared where an optional MD5 operation failed. The fix for that is identifying the failing MD5 operation, asserting that the error queue is empty before the call, and then discarding the error generated by the call after it.
I can offer https://salsa.debian.org/apt-team/apt/-/merge_requests/590 There are some more bugs in methods/connect.cc, HandleError() where we only look at the top error in the stack rather than all errors. Not yet sure how to fix this. Posted about the general issue in https://blog.jak-linux.org/2026/07/03/openssl-pandemic/
Hello, Bug #1140227 in apt reported by you has been fixed in the Git repository and is awaiting an upload. You can see the commit message below and you can check the diff of the fix at: https://salsa.debian.org/apt-team/apt/-/commit/dfeecf7f520b019a401c77ebba4f7547d43d9ab9 ------------------------------------------------------------------------ hashes: Fix lingering OpenSSL error Wrap the digest initialization into an error mark that we pop back to such that we do not end up with a lingering error when doing other operations. Closes: #1140227 (hopefully, otherwise it's an openssl bug) ------------------------------------------------------------------------ (this message was generated automatically) -- Greetings https://bugs.debian.org/1140227
We believe that the bug you reported is fixed in the latest version of
apt, which is due to be installed in the Debian FTP archive.
A summary of the changes between this version and the previous one is
attached.
Thank you for reporting the bug, which will now be closed. If you
have further comments please address them to 1140227@bugs.debian.org,
and the maintainer will reopen the bug report if appropriate.
Debian distribution maintenance software
pp.
Julian Andres Klode <juliank@ubuntu.com> (supplier of updated apt package)
(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing ftpmaster@ftp-master.debian.org)
Format: 1.8
Date: Thu, 30 Jul 2026 22:43:05 +0200
Source: apt
Architecture: source
Version: 3.3.2
Distribution: unstable
Urgency: medium
Maintainer: APT Development Team <deity@lists.debian.org>
Changed-By: Julian Andres Klode <juliank@ubuntu.com>
Closes: 1133965 1135221 1135222 1139336 1140227
Changes:
apt (3.3.2) unstable; urgency=medium
.
[ Julian Andres Klode ]
* Document and test combined `build-dep --arch-only --indep-only`
* ftparchive: fix heap overflow in ContentsExtract::DoItem
* deb: guard against unsigned underflow when trimming control newlines
* gpgv: don't advance past the null terminator in PushEntryWithKeyID
* ftparchive: replace ContentsExtract's manual buffer with std::vector<char>
* test: Limit valgrind to 1024 open files
* hashes: Fix lingering OpenSSL error (Closes: #1140227)
* test: use `gnurm` where available
* Convert command-line option-parsing to declarative format
* Fix crash when an aux file request is redirected
* Reply to aux requests with the original URI if redirected
* debian/apt-daily.service: Add timeouts.
30 mins for apt-daily.service, 12 hours for apt-daily-upgrade.service
should be sufficient. (LP: #2158000)
.
[ наб ]
* apt-transport-https(1): document host-specific SSLCert, SSLKey, Verify-Host with host:: instead of ::host
.
[ David Kalnischkies ]
* aptwebserver: Refuse client immediately on TLS handshake
.
[ Américo Monteiro ]
* Portuguese manpages translation update (Closes: #1133965)
.
[ Frans Spiesschaert ]
* Dutch program translation update (Closes: #1135221)
* Dutch manpages translation update (Closes: #1135222)
.
[ Remus-Gabriel Chelu ]
* Romanian program translation update (Closes: #1139336)
.
[ Mark Atwood ]
* hashes: include <span> for std::span
* hashes: don't crash on an unavailable digest
* test: exercise hashes with a disabled digest
.
[ dongshengyuan ]
* Fix installing a deb with colon in path
.
[ Simon Johnsson ]
* apt-pkg: rename "OpenPGP signature verification failed" to "Signature verification failed"
.
[ Andreas Noteng ]
* Norwegian Bokmål (nb) translation update
.
[ Temuri Doghonadze ]
* po: Add Georgian translation
.
[ Andriy Pysyk ]
* Update Ukrainian translation for 3.3.1
.
[ Mikhail Khachayants ]
* srvrec: reject res_query answers bigger than our buffer
.
[ Ramesh Adhikari ]
* tagfile: fix unbounded backward scan in Fill()'s trailing-newline check
Checksums-Sha1:
cc908164eab430cd2d913e727761f13773088bba 3132 apt_3.3.2.dsc
b11dc55fc4238aee345832f9673d1330d5c807e0 2500604 apt_3.3.2.tar.xz
394d4b63680d9c7eceec7825ff150829e6666ff3 7455 apt_3.3.2_source.buildinfo
Checksums-Sha256:
62b65b8ff473c9f6e99ab88f4bee84befef42075198201c67ff872c07da65dd6 3132 apt_3.3.2.dsc
97d2cb48a3a91994662ab879a39ae803dc7a08d6d93070262c9e3bdfa22ae928 2500604 apt_3.3.2.tar.xz
6d82d582e73e496a3512ad59ef540464968e96280fe5c0a9b608c19d5d9831d6 7455 apt_3.3.2_source.buildinfo
Files:
9f7aa40cc51aefe7ab6f23cc6a14a20b 3132 admin required apt_3.3.2.dsc
00f9e6c225e98a3e55c942d2a9667766 2500604 admin required apt_3.3.2.tar.xz
319742d81622e269c134d570168fab3e 7455 admin required apt_3.3.2_source.buildinfo
-----BEGIN PGP SIGNATURE-----
iQJDBAEBCgAtFiEET7WIqEwt3nmnTHeHb6RY3R2wP3EFAmpruFEPHGpha0BkZWJp
YW4ub3JnAAoJEG+kWN0dsD9xAGAP/jLMbjZm4GVyE6E0ba/psQQa5OyTjicYh7Lb
gQzJ8Nsucy10KohqgTI/GBGo/XzmC6o+LJb61kKOKJCb358tIwsJ7JqCgpKRZaaG
1m3UyVTWH0TC830VcOO19G3P9x234tosS8fRM+nbHqVrJHsncN2ncdT1kUEikhnL
tx76FSEjJ20aFfeWfLqNhWKg3Z396D/yhoZDWlQFOq/VOdT/0GAjh+1Kw8javOfr
XAfwJoD314MoOwDzDGzdsE3cO8eUvSIOPON5en5Jduwx4MPNvsA0jCcQnk6+b/bu
lJUxxMTVeimM+hRNzY+QDy9ClKLW7f+X5mZzw4JGRsnVtBCpIG09yg4eOw6jdZeL
x8UC//t+yTHO08IO+yjFQDwhl8IwPzKA2wLIAWUGkrv5lP/XT0oKRdyIUhCmBQJH
WZdv4hnpp795scdB1YnbW/N5gz5KqFA3V1IVE4/D/8FhhJywo001hbPzk7MEBv2V
XvZM3RxAVexSf0HoJ3rOF/SZPWcW/tFcUVkDME17PxgZpDvLf0upB30srNPOjLVJ
vJmXtLvYFM6UD3RfW8ER+vqewQ17PFPB3PVxUx9MdL0rtYMApmJPjzaoAT72andV
OV9XWtBWdQAtaT4SsCeS0SuyQwB7xzVV2D+j4jjlc85z9P6SxQtEjjozstzi5zsI
Ea0XJlM2
=GEAC
-----END PGP SIGNATURE-----