Description
Problem
I'm trying to cargo login
to a custom registry and store the token in the GNOME keyring via the libsecret provider, but it just gets stuck forever.
Steps
-
configure cargo to use the libsecret provider:
~/.cargo/config.toml:
[registry] global-credential-providers = ["cargo:token", "cargo:libsecret"]
-
CARGO_REGISTRIES_TEST1_INDEX=sparse+https://charts.jfrog.io/artifactory/api/cargo/xxx/index/ cargo login --registry test1
(this is some fairly random URL that happens to trigger the issue but it's not our private jfrog instance obviously) -
reply whatever (e.g. "x") to the "please paste the token for test1 below" prompt
Now cargo gets stuck after printing the following errors:
(process:19648): GLib-GObject-CRITICAL **: 15:31:30.977: cannot register existing type 'SecretService'
(process:19648): GLib-GObject-CRITICAL **: 15:31:30.977: cannot add private field to invalid (non-instantiatable) type '<invalid>'
(process:19648): GLib-GObject-CRITICAL **: 15:31:30.977: g_type_add_interface_static: assertion 'G_TYPE_IS_INSTANTIATABLE (instance_type)' failed
(process:19648): GLib-GObject-CRITICAL **: 15:31:30.977: g_type_add_interface_static: assertion 'G_TYPE_IS_INSTANTIATABLE (instance_type)' failed
(process:19648): GLib-GObject-CRITICAL **: 15:31:30.977: cannot register existing type 'SecretBackend'
(process:19648): GLib-GObject-CRITICAL **: 15:31:30.977: g_type_interface_add_prerequisite: assertion 'G_TYPE_IS_INTERFACE (interface_type)' failed
(process:19648): GLib-GObject-CRITICAL **: 15:31:30.977: g_type_interface_add_prerequisite: assertion 'G_TYPE_IS_INTERFACE (interface_type)' failed
(process:19648): GLib-CRITICAL **: 15:31:30.977: g_once_init_leave_pointer: assertion 'result != 0' failed
(process:19648): GLib-GObject-CRITICAL **: 15:31:30.977: g_type_add_interface_static: assertion 'G_TYPE_IS_INSTANTIATABLE (instance_type)' failed
Possible Solution(s)
I believe this is because the libsecret-1.so.0 library gets loaded and unloaded multiple times (once for the lookup, another time for the store):
but this isn't supported: https://mail.gnome.org/archives/gtk-list/2017-February/msg00006.html
Using something like LazyLock to load the library should resolve the issue.
There's a workaround — LD_PRELOAD can be used to prevent the dynamic library from getting unloaded:
LD_PRELOAD=/lib/aarch64-linux-gnu/libsecret-1.so.0 cargo login --registry
Notes
I think this only gets stuck on arm64. I've seen the glib errors on x86_64 as well but it didn't get stuck. gdb
tells me it's stuck in some futex/condition variable, but I don't think it's especially relevant as the root cause is (imo) well understood.
Version
cargo 1.87.0 (99624be96 2025-05-06)
release: 1.87.0
commit-hash: 99624be96e9d213b0e9b1e36451271f24e4a41d8
commit-date: 2025-05-06
host: aarch64-unknown-linux-gnu
libgit2: 1.9.0 (sys:0.20.0 vendored)
libcurl: 8.12.1-DEV (sys:0.4.80+curl-8.12.1 vendored ssl:OpenSSL/3.4.1)
ssl: OpenSSL 3.4.1 11 Feb 2025
os: Debian 13.0.0 (trixie) [64-bit]