Summary
cloudflared access token <url> times out on a metadata HEAD request even when a valid cached token exists in ~/.cloudflared/. The same request succeeds instantly via curl.
Version
cloudflared version 2026.3.0 (built 2026-03-06T12:53:40Z)
macOS Darwin 25.4.0 (arm64)
Reproduction
# 1. Login successfully (token cached)
cloudflared access login https://my-app.example.com
# 2. Verify cached token exists and is valid
ls ~/.cloudflared/my-app.example.com-*-token
# 3. Try to retrieve the token — times out
cloudflared access token https://my-app.example.com
# Error: failed to get app info: Head "https://org.cloudflareaccess.com/cdn-cgi/access/login/my-app.example.com?kid=...&meta=<jwt>&redirect_url=/": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Diagnosis
The failure is in the get app info step, which issues a HEAD request to:
https://<org>.cloudflareaccess.com/cdn-cgi/access/login/<hostname>?kid=<kid>&meta=<jwt>&redirect_url=/
This endpoint returns a 302 redirect to the protected origin (https://my-app.example.com/).
Via curl (works):
curl -s -o /dev/null -w "%{http_code} %{time_total}s" -I \
"https://org.cloudflareaccess.com/cdn-cgi/access/login/my-app.example.com?kid=...&redirect_url=%2F"
# 302 0.5s
Via cloudflared (fails):
Go's net/http client follows the 302 by default. The redirect target is the CF Access-protected origin, which either:
- Redirects back to the login endpoint (infinite loop), or
- Requires a valid CF Access token to respond (chicken-and-egg: we're calling
access token to get the token)
This causes the internal timeout.
Expected behavior
cloudflared access token should:
- Check if a valid (non-expired) cached token exists in
~/.cloudflared/
- If valid, return it without making any network requests
- Only hit the metadata endpoint when the token is expired or missing
The metadata HEAD should also use CheckRedirect to avoid following the 302, since the 302 itself confirms the app exists — the redirect target requires auth that the client doesn't have yet.
Workaround
Read the cached token directly and validate the JWT exp claim:
TOKEN_FILE=$(find ~/.cloudflared -name "my-app.example.com-*-token" | head -1)
TOKEN=$(cat "$TOKEN_FILE")
# Validate exp claim before using
Impact
This blocks all programmatic use of cloudflared access token when the metadata HEAD doesn't complete. Affects CI/CD pipelines, kubectl wrappers, and any automation that depends on cloudflared access token returning cached tokens reliably.
Summary
cloudflared access token <url>times out on a metadata HEAD request even when a valid cached token exists in~/.cloudflared/. The same request succeeds instantly viacurl.Version
Reproduction
Diagnosis
The failure is in the
get app infostep, which issues a HEAD request to:This endpoint returns a 302 redirect to the protected origin (
https://my-app.example.com/).Via curl (works):
Via cloudflared (fails):
Go's
net/httpclient follows the 302 by default. The redirect target is the CF Access-protected origin, which either:access tokento get the token)This causes the internal timeout.
Expected behavior
cloudflared access tokenshould:~/.cloudflared/The metadata HEAD should also use
CheckRedirectto avoid following the 302, since the 302 itself confirms the app exists — the redirect target requires auth that the client doesn't have yet.Workaround
Read the cached token directly and validate the JWT
expclaim:Impact
This blocks all programmatic use of
cloudflared access tokenwhen the metadata HEAD doesn't complete. Affects CI/CD pipelines, kubectl wrappers, and any automation that depends oncloudflared access tokenreturning cached tokens reliably.