dagger/dagger · error

item %s is locked

Error message

item %s is locked

What it means

The provider calls svc.Unlock(collection) and then checks each item's Locked() state. If an item is still locked after unlocking the collection, Unlock silently failed (a known quirk — Unlock doesn't always return an error on failure), so the provider throws this error rather than reading the secret.

Source

Thrown at engine/client/secretprovider/libsecret.go:77

	// get all items
	items, err := collection.Items()
	if err != nil {
		return nil, err
	}
	if len(items) == 0 {
		return nil, fmt.Errorf("no items found in collection %s", uri.Hostname())
	}
	for _, item := range items {
		locked, err := item.Locked()
		if err != nil {
			return nil, err
		}
		if locked {
			// something has gone *wrong* - we've just called Unlock on the
			// collection, so nothing should be locked (but this does seem to
			// happen, Unlock doesn't seem to always return an error on failure)
			return nil, fmt.Errorf("item %s is locked", item.Path())
		}
	}

	// filter items using the path
	var matching []libsecret.Item
	if uri.Path == "" {
		// path is empty, just grab all
		// libsecret://<collection>
		matching = items
		if len(uri.Query()) == 0 {
			return nil, fmt.Errorf("item %s must be filtered", key)
		}
	}
	if matching == nil {
		for _, candidate := range items {
			name := path.Base(string(candidate.Path()))
			if name == uri.Path {
				// path contains an auto-generated item specific identifier

View on GitHub (pinned to 82ba2681db)

Solutions

  1. Unlock the keyring beforehand (normal login with PAM auto-unlock, or secret-tool unlock).
  2. In headless environments, pre-unlock at session start via gnome-keyring-daemon --unlock with the keyring password.
  3. If using KeePassXC, open and unlock the database.
  4. Re-run and accept the unlock prompt when it appears.

Example fix

// before (headless CI: prompt cannot appear)
$ dagger query  # -> item .../item1 is locked
// after (CI setup step)
echo -n "$KEYRING_PASS" | gnome-keyring-daemon --unlock --replace
Defensive patterns

Strategy: try-catch

Validate before calling

// pre-flight: ensure the collection's items are unlocked
svc, _ := libsecret.NewService()
coll, _ := findCollection(svc, name)
items, _ := coll.Items()
for _, it := range items {
	locked, _ := it.Locked()
	if locked {
		_ = svc.Unlock(coll) // resolve prompts before the real lookup
	}
}

Try / catch

if err != nil && strings.Contains(err.Error(), "is locked") {
	return fmt.Errorf("keyring still locked — unlock it (PAM login, secret-tool unlock, or gnome-keyring-daemon --unlock) and retry: %w", err)
}

Prevention

When it happens

Trigger: libsecret://<collection>/... where the collection's Unlock triggered a prompt that was dismissed, timed out, or could not be shown (headless session), leaving items locked.

Common situations: Headless CI/container environments with no prompt agent to answer the keyring unlock dialog; user cancelled the GNOME unlock prompt; PAM auto-unlock not configured; KeePassXC database locked.

Related errors


AI-assisted analysis of dagger/dagger@82ba2681db (2026-09-05). Data as JSON: /api/errors/e6e8ef4d1b9a125c. Report an issue: GitHub.