basecamp/kamal · error · RuntimeError
Could not read #{secrets} from AWS Secrets Manager
Error message
Could not read #{secrets} from AWS Secrets Manager What it means
The AWS Secrets Manager adapter shells out to `aws secretsmanager batch-get-secret-value --secret-id-list ... [--profile X] --output json`; if that CLI process exits non-zero, Kamal raises RuntimeError. Note the message interpolates the raw CLI output, not the secret names, because the `tap do |secrets|` block variable shadows the secrets array — so the message shows whatever aws printed (often empty, since stderr is not captured).
Source
Thrown at lib/kamal/secrets/adapters/aws_secrets_manager.rb:37
results["#{secret_name}/#{key}"] = stringify_secret_value(value)
end
else
results["#{secret_name}"] = stringify_secret_value(secret_string)
end
rescue JSON::ParserError
results["#{secret_name}"] = secret["SecretString"]
end
end
end
def get_from_secrets_manager(secrets, account: nil)
args = [ "aws", "secretsmanager", "batch-get-secret-value", "--secret-id-list" ] + secrets.map(&:shellescape)
args += [ "--profile", account.shellescape ] if account
args += [ "--output", "json" ]
cmd = args.join(" ")
`#{cmd}`.tap do |secrets|
raise RuntimeError, "Could not read #{secrets} from AWS Secrets Manager" unless $?.success?
secrets = JSON.parse(secrets)
return secrets["SecretValues"] unless secrets["Errors"].present?
raise RuntimeError, secrets["Errors"].map { |error| "#{error['SecretId']}: #{error['Message']}" }.join(" ")
end
end
def stringify_secret_value(value)
value.is_a?(String) ? value : JSON.dump(value)
end
def check_dependencies!
raise RuntimeError, "AWS CLI is not installed" unless cli_installed?
end
def cli_installed?View on GitHub (pinned to eee0083b38)
Solutions
- Reproduce manually with the exact command from the source: aws secretsmanager batch-get-secret-value --secret-id-list <name> --output json (add --profile if used) and read the stderr
- Fix credentials: aws sso login (or refresh keys), and verify with aws sts get-caller-identity using the same profile
- Set the region explicitly, e.g. export AWS_REGION=us-east-1, if the CLI has no default region
- Upgrade to a current AWS CLI v2 (batch-get-secret-value is not in old v2 releases/v1)
Example fix
# before (failing) kamal secrets fetch -a aws_secrets_manager --account prod RAILS_MASTER_KEY # debug + fix (terminal) aws sts get-caller-identity --profile prod # verify creds aws sso login --profile prod # refresh if expired aws secretsmanager batch-get-secret-value --secret-id-list RAILS_MASTER_KEY --profile prod --output json
Defensive patterns
Strategy: try-catch
Validate before calling
# Verify AWS auth/CLI health before running kamal
system("aws --version > /dev/null 2>&1") or abort "aws CLI missing"
system("aws sts get-caller-identity #{ENV["AWS_PROFILE"] ? "--profile #{ENV["AWS_PROFILE"]}" : ""} > /dev/null") or abort "AWS credentials invalid/expired" Try / catch
begin
results = adapter.fetch(secret_names, account: "prod")
rescue RuntimeError => e
warn "aws CLI failure — re-run manually: aws secretsmanager batch-get-secret-value --secret-id-list #{secret_names.join(' ')} --profile prod --output json"
warn e.message
exit 1
end Prevention
- Refresh SSO tokens before fetch jobs: aws sso login --profile <p> as a pipeline pre-step
- Pin a modern awscli v2 in CI images; batch-get-secret-value needs a recent release
- Set AWS_REGION explicitly in automation so the CLI never fails on missing region config
When it happens
Trigger: Expired SSO token or missing/invalid AWS credentials; wrong profile name passed via --account; awscli too old to have batch-get-secret-value; no network reachability to secretsmanager.<region>.amazonaws.com; the AWS_REGION/region not configured so the CLI errors out.
Common situations: CI job whose aws SSO session expired overnight; profile typo between deploy scripts; fresh machine with awscli v1 installed; corporate proxy or VPC without an secretsmanager endpoint.
Related errors
- AWS CLI is not installed
- Unknown secrets adapter: #{name}
- #{error['SecretId']}: #{error['Message']}
- Missing required option '--account'
- Failed to login to and unlock Bitwarden
AI-assisted analysis of basecamp/kamal@eee0083b38 (2026-08-21).
Data as JSON: /api/errors/eab78a1603d71807.
Report an issue: GitHub.