basecamp/kamal · error · RuntimeError
Failed to login to Passbolt
Error message
Failed to login to Passbolt
What it means
Raised in Passbolt#login when `passbolt verify` exits non-zero. Unlike other adapters there is NO loggedin? short-circuit — every single fetch runs `passbolt verify` first, so any Passbolt CLI configuration problem (missing GPG key, wrong server URL, bad fingerprint, expired passphrase cache) turns every kamal secrets pull into this error. The adapter sets requires_account? false; authentication state lives entirely in the passbolt CLI's own config.
Source
Thrown at lib/kamal/secrets/adapters/passbolt.rb:10
class Kamal::Secrets::Adapters::Passbolt < Kamal::Secrets::Adapters::Base
def requires_account?
false
end
private
def login(*)
`passbolt verify`
raise RuntimeError, "Failed to login to Passbolt" unless $?.success?
end
def fetch_secrets(secrets, from:, **)
secrets = prefixed_secrets(secrets, from: from)
raise ArgumentError, "No secrets given to fetch" if secrets.empty?
secret_names = secrets.collect { |s| s.split("/").last }
folders = secrets_get_folders(secrets)
# build filter conditions for each secret with its corresponding folder
filter_conditions = []
secrets.each do |secret|
parts = secret.split("/")
secret_name = parts.last
if parts.size > 1
# get the folder path without the secret name
folder_path = parts[0..-2]View on GitHub (pinned to eee0083b38)
Solutions
- Run `passbolt verify` directly to see its error output, then fix what it complains about (usually configuration or GPG key).
- Configure the CLI: `passbolt configure --url https://passbolt.example.com --userKey <fingerprint>` (exact flags per your passbolt CLI version) after importing the user's GPG secret key with `gpg --import`.
- Verify server reachability and TLS (curl the URL) if configuration is correct but verify still fails.
- Re-run `kamal secrets pull` only after `passbolt verify` exits 0 standalone.
Example fix
# before: unconfigured passbolt CLI # -> RuntimeError: Failed to login to Passbolt # after: import key + configure, verify standalone gpg --import passbolt-user-private.asc passbolt configure --url https://passbolt.example.com passbolt verify && kamal secrets pull
Defensive patterns
Strategy: try-catch
Validate before calling
require "open3"
def passbolt_verified?
Open3.capture3("passbolt", "verify")[2].success?
end
abort "passbolt CLI not configured/verified: run `passbolt configure` and import your GPG key" unless passbolt_verified? Try / catch
begin
secrets = adapter.fetch(names)
rescue RuntimeError => e
if e.message == "Failed to login to Passbolt"
raise "passbolt verify failed: check CLI config, GPG secret key, and server reachability before deploying"
end
raise
end Prevention
- Run `passbolt verify` in a preflight step — the adapter re-runs it on every fetch, so keep the CLI permanently configured.
- Import the Passbolt user's GPG secret key and record the correct fingerprint in CLI config during provisioning.
- Monitor Passbolt server cert/hostname changes; verify fails before kamal gives a clearer error.
When it happens
Trigger: adapter.fetch(...) whenever `passbolt verify` fails: passbolt CLI never configured (no server/user/GPG key set), GPG secret key for the Passbolt user missing from the local keyring, wrong fingerprint or server URL in the CLI config, or the server unreachable/SSL failing.
Common situations: New machine or CI container where the passbolt CLI was installed but `passbolt configure` was never run; GPG key not imported (gpg --import) after OS reinstall; Passbolt server hostname or self-signed cert changed; user account key rotated in Passbolt but local keyring still holds the old one.
Related errors
- Could not authenticate to Bitwarden Secrets Manager. Did you
- Failed to login to Doppler
- could not login to gcloud
- Failed to login to LastPass
- Could not read #{secrets} from Doppler
AI-assisted analysis of basecamp/kamal@eee0083b38 (2026-08-21).
Data as JSON: /api/errors/51533d7c12653546.
Report an issue: GitHub.