Skip to content

Troubleshooting & FAQ

Quick fixes for the things people actually hit. For the long-form CLI manual, tvault help troubleshooting.

Exit codes

tvault returns meaningful exit codes, so scripts can branch on them:

CodeMeaning
0Success
1Generic error
3Vault is locked at rest
4Secret or project not found
5Vault not initialized
6Wrong passphrase
7Vault database is in use by another process (e.g. a running tvault studio)

"Vault is locked" / "wrong passphrase"

The vault is encrypted; reads need it unlocked.

  • Interactively: tvault unlock (or just run a command — you'll be prompted).
  • Non-interactively (CI, scripts, MCP): set TVAULT_PASSPHRASE in the environment, or point TVAULT_PASSPHRASE_FILE (or agent.passphrase_file) at a 0600 env file. See Environment Variables.
  • Exit code 6 means the passphrase was wrong; 3 means it's locked and no passphrase was available.
  • A running agent does not satisfy this for a write. It serves reads only, so set / delete / import / rotate still need the passphrase — see the next section.

"vault is locked" from a tvault nested inside tvault run

The same command works on its own but fails with exit code 3 inside tvault run (or MCP vault_run_with_secrets), even with the agent running:

bash
tvault set PROBE x -p demo                                   # works
tvault run --only API_KEY -- tvault set PROBE x -p demo      # "vault is locked"

This is two deliberate boundaries meeting, not a broken socket:

  1. A launched child inherits no TVAULT_* variable. tvault run and MCP exec strip every one of them before starting the child, so the parent's TVAULT_PASSPHRASE never reaches it. That is what keeps a subprocess from receiving the key to the whole vault when you handed it two values. See Security.
  2. The agent serves reads, not unlocks. It caches the key and answers get / getall / getselected — it has no write operation and never hands the key out. So set, delete, import, rotate and friends need the passphrase whether or not an agent is running.

Together: nested reads work (they route through the agent), nested writes do not.

Fixes, best first:

  • Move the write out of tvault run. The wrapper exists to inject values into one process; vault administration belongs beside it, not inside it.

  • Give that one child its own credential, explicitly, if it truly must write:

    bash
    tvault run --only API_KEY -- sh -c 'TVAULT_PASSPHRASE=... tvault set PROBE x -p demo'

    Understand the trade: that child now holds the passphrase to every project and version, which is exactly what --only was narrowing.

"vault not found" / "not initialized"

Exit code 5. Create a vault first:

bash
tvault init

By default the vault lives at ~/.tvault/vault.db (override with --vault or TVAULT_DIR). See Configuration.

The MCP server won't connect

The MCP server (tvault mcp) speaks JSON-RPC over stdio and unlocks the vault at startup — there is no prompt over a pipe.

  • "Connection closed" right away → the server couldn't unlock. The host must pass TVAULT_PASSPHRASE in the server's env. Use the host's environment controls or a credential-store launcher — see MCP Overview → Before you connect.
  • After changing the passphrase the cached key is stale → restart your MCP/agent sessions so they reconnect with the new one.
  • Tools appear but calls are denied → the Access Policy is gating them (access_mode, allow_exec, project/secret globs). Check ~/.tvault/mcp-policy.yaml.

"vault is locked by another tvault process" (exit code 7)

The on-disk store (bbolt) is single-writer: only one process can hold the database open at a time.

tvault mcp and tvault agent no longer block the CLI — they cache only the key and reopen the vault per request, releasing the lock between calls, so set/get/run/import keep working alongside them. The remaining long-lived holder is tvault studio, which keeps the vault open for the duration of the interactive session.

If you hit exit code 7 (or doctor reports "in use by another process"), quit the other tvault studio window (or whatever foreground process is holding it) and retry. This used to surface as an opaque open bolt db: timeout.

tvault agent says "unix-only"

The local agent is Linux/macOS only — on Windows it returns "unsupported platform". Use the direct CLI or the MCP server instead; both work everywhere.

"project has no recipients"

vault_export_env_encrypted (and tvault seal with no --recipient/.tvault-recipients) seal to the project's current recipients. If none are set, share the project first:

bash
tvault projects share tvault1…          # CLI

…or use tvault seal --recipient tvault1… / vault_seal_for_recipients with explicit recipients. See Sharing and Committable Secrets.

tvault studio won't start

The studio needs an interactive terminal — it refuses to run under TERM=dumb or when stdout isn't a TTY (e.g. piped, or some CI shells). Run it in a real terminal, or use the CLI/MCP for non-interactive access.

"identity export refuses to print"

tvault identity export prints a private key, so it refuses to write to a non-terminal (to avoid landing in a captured log). Pipe it deliberately with --force:

bash
tvault identity export ci --force | gh secret set TVAULT_IDENTITY_KEY

Rotating the passphrase broke my .env.encrypted

tvault key rotate re-wraps the vault keys but invalidates v1 (passphrase-tied) .env.encrypted files. Use the v2, recipient-based format (encrypt-env --recipient / seal), which is KEK-independent and survives rotation. See Committable Secrets.

FAQ

Where is my data? One local bbolt database at ~/.tvault/vault.db (0600), in a 0700 directory. Secret payloads and key material are encrypted; names, timestamps, versions, audit entries, and other operational metadata remain readable to someone who can read the file. Identities, optional config, and the MCP policy live beside it. See Configuration.

I forgot my passphrase — can I recover it? No. There is no escrow or recovery key by design (local-first). Keep a backup of the passphrase (e.g. in a password manager). You can still share/recover projects via identities if you set them up beforehand.

Can an AI agent read my secret values? Yes, if its policy permits the explicit vault_get_secret tool; vault_set_secret can also receive a plaintext value from the client. Prefer metadata search plus vault_run_with_secrets when the value does not need to enter the conversation, and remember that subprocess output redaction is only a safety net. See the MCP safety model and Security.

Is it safe to commit .env.encrypted / .tvault-recipients? Yes — .env.encrypted is ciphertext and .tvault-recipients holds only public keys. Never commit ~/.tvault/, *.key identity files, or a plaintext .env.

Does it work on Windows? The CLI and MCP server: yes (amd64/arm64). The unlock-once agent: no (unix only).

How do I back up the vault? tvault backup <path> copies vault.db without decrypting its records. The matching passphrase restores the complete owner view; a pre-provisioned recipient identity can read only projects shared to it. Operational metadata remains readable, so treat the backup as sensitive. See Key Management.

See also

Released under the MIT License.