Vault "missing client token" (VAULT_TOKEN not set) in CI
Vault received a request with no X-Vault-Token header. In CI this almost always means VAULT_TOKEN was never set, the login step failed silently, or the token did not carry across steps.
What this error means
Any authenticated call fails with "Error making API request ... Code: 400 ... * missing client token", even though VAULT_ADDR is reachable.
Error making API request.
URL: GET https://vault.example.com/v1/secret/data/ci/app
Code: 400. Errors:
* missing client tokenCommon causes
VAULT_TOKEN was never exported
The read step ran before (or without) a login, so no token is in the environment for the CLI or API client to send.
The token did not cross the step boundary
A vault login in one run: step does not persist VAULT_TOKEN into later steps unless you write it to $GITHUB_ENV or the output.
How to fix it
Log in and export the token to later steps
- Authenticate with your CI auth method (AppRole, JWT/OIDC, Kubernetes).
- Capture the returned token and write it to
$GITHUB_ENVso subsequent steps inherit it. - Do not print the token; mask it.
TOKEN=$(vault write -field=token auth/approle/login \
role_id="$ROLE_ID" secret_id="$SECRET_ID")
echo "::add-mask::$TOKEN"
echo "VAULT_TOKEN=$TOKEN" >> "$GITHUB_ENV"Let hashicorp/vault-action handle the token
The official action authenticates and fetches secrets in one step, so you never manage VAULT_TOKEN by hand.
- uses: hashicorp/vault-action@v3
with:
url: ${{ secrets.VAULT_ADDR }}
method: approle
roleId: ${{ secrets.VAULT_ROLE_ID }}
secretId: ${{ secrets.VAULT_SECRET_ID }}
secrets: secret/data/ci/app token | APP_TOKENHow to prevent it
- Fail the job if the login step returns no token instead of continuing.
- Propagate
VAULT_TOKENvia$GITHUB_ENV, not by re-running login per step. - Prefer hashicorp/vault-action so token handling is not manual.