Skip to content
Latchkey

JFrog "access token expired" in CI

The access token used by CI has expired. JFrog access tokens carry an expiry, and once past it every authenticated request is rejected until a fresh token is issued.

What this error means

jf commands that worked yesterday now fail with "token expired", "invalid token", or a sudden 401 across the whole pipeline.

jf
[Error] server response: 401 Unauthorized
{
  "errors": [ { "status": 401, "message": "Token expired" } ]
}

Common causes

The token passed its expiry

A time-boxed access token stored as a secret reached its expiry, so Artifactory rejects it everywhere at once.

A short-lived token reused across many runs

A token minted with a brief lifetime was cached as a secret and kept in use past its window.

How to fix it

Rotate the token secret

  1. Generate a fresh access token in the JFrog Platform.
  2. Update the JF_ACCESS_TOKEN secret with the new value.
  3. Re-run the pipeline; the 401s clear.
Terminal
jf rt ping --url "$JF_URL" --access-token "$JF_ACCESS_TOKEN"

Use OIDC for short-lived per-run tokens

Exchange a GitHub OIDC token for a fresh Artifactory token each run so nothing expires between runs.

.github/workflows/ci.yml
- uses: jfrog/setup-jfrog-cli@v4
  with:
    oidc-provider-name: github-actions
  env:
    JF_URL: ${{ vars.JF_URL }}

How to prevent it

  • Prefer OIDC so CI mints a fresh short-lived token each run.
  • If using static tokens, choose a longer expiry and track renewal.
  • Rotate the secret in one place when a token nears expiry.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →