moonD4rk/HackBrowserData · error

no vault for browser %q in keys (have: %s)

Error message

no vault for browser %q in keys (have: %s)

What it means

BuildFromDump restores browser instances from a previously exported master-key dump, selecting the vault whose Browser field matches the requested filter. When a filter is given but no vault in the dump matches (case-insensitively), the function fails and lists which vaults are available to help correct the name. The dump's vault names are the authoritative set.

Source

Thrown at browser/keydump.go:82

//
// Data layout is resolved two ways. When dataDir holds per-key subdirs (the archive layout), each
// vault is rooted at dataDir/<key>. Otherwise dataDir is treated as one browser's User Data (a
// hand-copied folder), which is unambiguous only for a single vault — so filter must pick one.
func BuildFromDump(dump masterkey.Dump, dataDir, filter string) ([]Browser, error) {
	filter = strings.ToLower(filter)
	if filter == "all" {
		filter = ""
	}

	var selected []masterkey.Vault
	for _, v := range dump.Vaults {
		if filter != "" && !strings.EqualFold(v.Browser, filter) {
			continue
		}
		selected = append(selected, v)
	}
	if filter != "" && len(selected) == 0 {
		return nil, fmt.Errorf("no vault for browser %q in keys (have: %s)", filter, vaultKeys(dump))
	}

	if !dirExists(dataDir) {
		return nil, fmt.Errorf("data dir %q does not exist", dataDir)
	}

	archiveLayout := isArchiveLayout(dataDir, selected)
	if !archiveLayout && len(selected) > 1 {
		return nil, fmt.Errorf("--data-dir %q has no per-browser subdir but keys has %d browsers; "+
			"point it at the archive root, or use -b <browser> for one browser's User Data (have: %s)",
			dataDir, len(selected), vaultKeys(dump))
	}

	var browsers []Browser
	for _, v := range selected {
		root := dataDir
		if archiveLayout {
			root = filepath.Join(dataDir, strings.ToLower(v.Browser))

View on GitHub (pinned to 0503d04d7a)

Solutions

  1. Use one of the names listed in the error's (have: ...) set as the filter value.
  2. Pass an empty filter "" to process all vaults in the dump instead of a specific browser.
  3. Regenerate the keys dump so it includes the target browser's vault.
  4. Match the dump's exact vault name (check spelling/spacing) when filtering.

Example fix

// before: name not present in dump
browser.BuildFromDump(dump, dataDir, "chrome")
// after: use a vault name actually in the dump
browser.BuildFromDump(dump, dataDir, "brave")
Defensive patterns

Strategy: validation

Validate before calling

names := make([]string, 0, len(dump))
for k := range dump { names = append(names, k) }
if filter != "" && !slices.Contains(names, strings.ToLower(filter)) {
    return fmt.Errorf("filter %q not in dump vaults %v", filter, names)
}

Try / catch

browsers, err := browser.BuildFromDump(dump, dataDir, "brave")
if err != nil && strings.HasPrefix(err.Error(), "no vault for browser") {
    // retry with empty filter or a listed vault name
    browsers, err = browser.BuildFromDump(dump, dataDir, "")
}

Prevention

When it happens

Trigger: Calling BuildFromDump(dump, dataDir, filter) with a non-empty filter whose value matches no vault's Browser field in the keys dump — e.g. "chrome" when the dump only holds "firefox" or "brave" vaults.

Common situations: Typo or different casing/naming in the filter ("Chrome" vs "chromium"), filtering a dump produced on another machine with different browsers, or a dump missing the target browser because its keys were never extracted.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


AI-assisted analysis of moonD4rk/HackBrowserData@0503d04d7a (2026-09-06). Data as JSON: /api/errors/1141ae216a7709af. Report an issue: GitHub.