docker/cli · error

failed to parse token claims

Error message

failed to parse token claims: %w

What it means

Returned by OAuthManager.Login when oauth.GetClaims(tokenRes.AccessToken) fails. After the device flow returns an access token, the manager parses its JWT claims to extract the username/domain; if the token is malformed or claims cannot be extracted, login aborts before storing anything.

Solutions

  1. Retry `docker login` to obtain a fresh access token.
  2. Update the CLI to the latest version (GetClaims contract may have changed).
  3. Check no proxy is mutating the token body.
  4. If recurring, fall back to a manual PAT login.

Example fix

# before
docker login  # -> failed to parse token claims
docker logout
docker login   # fresh token
# fallback
docker login -u myuser  # PAT as password
Defensive patterns

Strategy: try-catch

Try / catch

// claims parse failure -> retry once, then fall back to PAT login
if strings.Contains(err.Error(), "failed to parse token claims") { fallBackToPAT() }

Prevention

When it happens

Trigger: The tenant issued an access token that is not a parseable JWT or whose claims do not contain the expected domain/username fields.

Common situations: Tenant returned a non-JWT bearer token; token was truncated/mangled by a proxy; tenant schema change; clock/signature verification failure inside GetClaims.

Understand the failure class

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/4ba0802ad912f1f7. Report an issue: GitHub.

Appendix: source

Thrown at internal/oauth/manager/manager.go:139

	go func() {
		reader := bufio.NewReader(os.Stdin)
		_, _ = reader.ReadString('\n')
		_ = m.openBrowser(state.VerificationURI)
	}()

	_, _ = fmt.Fprint(w, "\nWaiting for authentication in the browser…\n")
	var tokenRes api.TokenResponse
	select {
	case <-ctx.Done():
		return nil, errors.New("login canceled")
	case err := <-waitForTokenErrChan:
		return nil, fmt.Errorf("failed waiting for authentication: %w", err)
	case tokenRes = <-tokenResChan:
	}

	claims, err := oauth.GetClaims(tokenRes.AccessToken)
	if err != nil {
		return nil, fmt.Errorf("failed to parse token claims: %w", err)
	}

	err = m.storeTokensInStore(tokenRes, claims.Domain.Username)
	if err != nil {
		return nil, fmt.Errorf("failed to store tokens: %w", err)
	}

	pat, err := m.api.GetAutoPAT(ctx, m.audience, tokenRes)
	if err != nil {
		return nil, err
	}

	return &types.AuthConfig{
		Username:      claims.Domain.Username,
		Password:      pat,
		ServerAddress: registry.IndexServer,
	}, nil
}

View on GitHub (pinned to 4f84911bfe)