tl;dr - had many issues with the fingerprint on fedora 44 and have a band-aid solution killing/restarting fprintd on suspend/wake with no issues since.
I’ve been on a new FW13 pro and fedora 44 for about 5 weeks - For the first few weeks I encountered intermittent fingerprint auth issues in around 1 in 3 wake-ups - which is incredibly annoying because one can’t even login with a password and must keep sleeping/waking up and hoping it works.
After endless back and forth with Claude, a month of logging and failed attempts to fix this, it seems the issue is that the goodix driver doesn’t seem to support suspend/resume hooks causing issues on suspend/wake:
In libfprint 1.94.100 there are about 44 driver files. Exactly three set the suspend and resume hooks: Synaptics, FPC MOC, and Egis MOC. Goodix MOC, which covers your reader and about 30 other Goodix product IDs, does not. So the capable drivers are the minority, but they happen to be the two most common laptop sensors besides Goodix.
How a capable driver avoids this
When suspend arrives mid-scan, the Synaptics driver puts its command state machine on hold and reports success. The library then does not cancel the verify, no error reaches the lock screen, the lock screen keeps its connection, and on resume the scan carries on. Nothing is ever closed during the sleep window, so the problem below never arises.
What actually happens with Goodix, corrected
I previously described a cleanup race. The source shows it is deterministic:
- With no suspend hook, the library marks the device as suspended and cancels the scan with “Cannot run while suspended”. That part is intended behaviour.
- The lock screen’s verify fails, so it drops its connection. fprintd reacts by closing the device.
- The library refuses every operation while the device is marked suspended, including close. That is the “still busy” error. It is a rule, not a race.
- fprintd logs the error, forgets the session, and gives up. The device stays open inside the library forever.
- After resume, each unlock calls Claim, fprintd tries to open, and the library answers “already opened” instantly. fprintd does not log that error, which is why the claims looked like they hung. They did not. The audit log shows the fingerprint service failing in the same second as each claim, and the lock screen retrying it over and over. 143 of the 162 such failures in 60 days fell inside a wedged daemon.
So this is an fprintd bug, triggered by any driver without suspend support whenever the client disconnects during the sleep window. Goodix is simply the common driver that lacks the hook.
So for better or worse, its band-aid solution was to setup a service to kill/restart fprintd on a suspend or resume to ensure it doesn’t have stale/broken state:
#!/usr/bin/env bash
# Install: /usr/lib/systemd/system-sleep/10-fprintd-stop (mode 0755, root)
# Log: journalctl -t fprintd-stop
#
# Stop fprintd before every suspend. fprintd is D-Bus activated and normally
# exits ~30s after use, but if a fingerprint operation is interrupted (e.g. lid
# closed mid-scan) the device close fails and the daemon is left wedged: it
# accepts Claim() calls but never opens the sensor, its idle-exit never fires,
# and it survives suspend after suspend, breaking every unlock until it dies.
# Killing it here guarantees a fresh process on the next unlock. Nothing is
# lost: enrolled prints live on disk in /var/lib/fprint.
TAG=fprintd-stop
case "$1" in
pre)
if systemctl is-active --quiet fprintd.service; then
logger -t "$TAG" "stopping fprintd before $2"
systemctl kill --signal=SIGTERM fprintd.service
# Give it up to ~2s, then force it. Never delay suspend longer.
for _ in 1 2 3 4 5 6 7 8 9 10; do
systemctl is-active --quiet fprintd.service || break
sleep 0.2
done
if systemctl is-active --quiet fprintd.service; then
logger -t "$TAG" "fprintd ignored SIGTERM (wedged) - sending SIGKILL"
systemctl kill --signal=SIGKILL fprintd.service
fi
fi
;;
post)
# Belt and braces: if anything started fprintd during the suspend
# path, make sure the first unlock after resume gets a fresh process.
if systemctl is-active --quiet fprintd.service; then
logger -t "$TAG" "fprintd alive after resume - restarting it"
systemctl kill --signal=SIGKILL fprintd.service
fi
;;
esac
exit 0
It drafted an issue that I feel details the issue better than I have:
Title: Device left open forever when a client disconnects while the device is suspended (drivers without suspend support, e.g. goodixmoc); every later Claim() fails with ALREADY_OPEN until fprintd exits
Environment
Summary
If the system suspends while a verify/identify is in flight on a driver that does not implement
suspend (goodixmoc here), libfprint cancels the operation and marks the device suspended, the
client’s verify fails, the client disconnects, and fprintd’s _fprint_device_client_vanished
tries to close the device. libfprint refuses because the device is suspended (FP_DEVICE_ERROR_BUSY).
fprintd logs a critical, drops the session, and never retries. The FpDevice stays open inside the
daemon. After resume every Claim() calls fp_device_open(), which immediately returns
FP_DEVICE_ERROR_ALREADY_OPEN; fprintd returns that to the client without logging it. The daemon
never idle-exits (there is always a client in the retry loop), so the breakage persists across
suspends until the process happens to die. One such process lived 34 h.
Users see: no fingerprint prompt at the lock screen, and the desktop retrying the fingerprint PAM
service repeatedly. This is very easy to hit on GNOME: the lock screen arms the reader the moment
the screen locks, so a scan is routinely in flight when the lid closes.
Sequence (verified against the source)
PrepareForSleep(true) → fp_device_suspend() → fpi_device_suspend()
(libfprint/fpi-device.c:1746). The driver has no suspend vfunc, so
fpi_device_suspend_complete(NOT_SUPPORTED) is called.
fpi_device_suspend_complete() (fpi-device.c:1941) sets is_suspended = TRUE and cancels the
current action with “Cannot run while suspended.” This is the documented behaviour.
- The verify fails, the PAM client gets the error and drops its bus connection.
_fprint_device_client_vanished() (src/device.c:988-999) calls fp_device_close_sync().
fp_device_close() (libfprint/fp-device.c:925) rejects it with FP_DEVICE_ERROR_BUSY because
priv->is_suspended is set. fprintd logs
Error closing device after disconnect: The device is still busy with another operation
and then unconditionally does session_data_set_new (priv, NULL, NULL).
The device is now open in libfprint with no session in fprintd.
PrepareForSleep(false) → fp_device_resume() clears is_suspended; nothing closes the device.
- Next
Claim() → fprint_device_claim() → fp_device_open() → priv->is_open is TRUE →
FP_DEVICE_ERROR_ALREADY_OPEN (“The device has already been opened!”). dev_open_cb() returns
FPRINT_ERROR_INTERNAL "Open failed with error: ..." to the client and does not log.
Every subsequent Claim does the same until the process exits.
Logs
Wedge forming (G_MESSAGES_DEBUG=all), 2026-10-15 12:23:22, PID 17306:
Preparing devices for sleep
Device reported suspend completion (error: [FP_DEVICE_ERROR_NOT_SUPPORTED] The operation is not supported on this device!)
[goodixmoc] SSM GOODIX_CMD_NUM_STATES failed in state 2 with error: Operation was cancelled
[goodixmoc] SSM identify failed in state 1 with error: Operation was cancelled
Device reported identify completion (error: [G_IO_ERROR_CANCELLED] Operation was cancelled)
verify_cb: result verify-unknown-error
Device reported an error during verify: Cannot run while suspended.
Released delay inhibitor for sleep.
Error closing device after disconnect: The device is still busy with another operation, please try again later.
Every unlock in that process afterwards (same PID, next day):
10:42:40 Preparing devices for resume
10:42:40 Device reported resume completion (error: none)
10:42:46 Authorization granted to :1.378 to call method ‘Claim’ for device ‘Goodix MOC Fingerprint Sensor’!
10:42:46 user ‘xxxxx’ claiming the device: 0
<no “Completing action FPI_DEVICE_ACTION_OPEN”, no “claimed device”>
10:42:46 audit: op=PAM:authentication grantors=? acct=“xxxxx” exe=“/usr/libexec/gdm-session-worker” res=failed
10:43:13 … Claim … claiming the device: 0 → PAM failure in the same second
10:44:31, 10:44:34, 10:44:36, 10:44:36, 10:44:37, 10:44:38, 10:44:39: same (lock screen retrying)
21 Claims in that process after the wedge, 0 opens, 0 matches. A healthy process does
claim → open completion → VerifyStart → match in about 1 s.
Evidence over 60 days of journal (one machine)
The two lines “Cannot run while suspended” and “Error closing device after disconnect: … still busy”
are logged without debug, so every episode can be checked.
- 17 fprintd processes logged “Cannot run while suspended”. All 17 occurred within 1 s of
systemd-suspend.service starting. 12 of 17 also logged the failed close (in the other 5 the
client had presumably not yet disconnected; outcome identical).
- After the error, 0 fingerprint successes in any of those 17 processes. 143 of 162 GDM
fingerprint-service failures in the period fell inside one of them.
- Lifetimes of the 17 processes: 2 min to 34 h, 14 of 17 longer than 5 min. A healthy process
idle-exits ~30 s after use.
- In every case fingerprint worked again within minutes of that process exiting.
- 403 processes without the error: 690 fingerprint successes.
- Exposure: 25 suspends began while a healthy fprintd had a scan in flight; 17 of them (68%) produced the wedge.
- USB-level state (presence, power/persist, autosuspend) was instrumented around every suspend for
4 weeks and was never the cause: the device was present in all 522 samples.
Expected
fprintd should not leave an FpDevice open with no session after a failed close. Options:
- In
_fprint_device_client_vanished, if fp_device_close_sync() fails with BUSY while suspended,
remember that a close is pending and perform it in the resume path (fprint_device_resume), or
- In
fprint_device_claim, if fp_device_open() fails with ALREADY_OPEN and there is no session,
close and re-open (or treat the device as already open), or
- Exit the process on an unrecoverable device state so D-Bus activation restarts it cleanly.
Driver side (libfprint)
Only three drivers implement suspend/resume in 1.94.100: synaptics, fpcmoc, egismoc.
goodixmoc does not, so the cancel-on-suspend path above is taken every time. Adding suspend/resume
to goodixmoc (as synaptics does: hold the interrupt wait, resume it afterwards) would avoid the
trigger for this hardware, but the fprintd handling above is wrong for every other driver without it.
Workaround in use
A systemd-sleep hook that kills fprintd before every suspend (SIGTERM, SIGKILL after 2 s) and after
resume. Since installing it: 8 suspends, 0 errors, 20 fingerprint logins, 0 failures.