goharbor/harbor · error

missing OAuth token

Error message

missing OAuth token

What it means

TokenAuthHandler.Authorize rejects a preheat request when the provider instance uses OAUTH auth mode but the credential data map has no "token" key — the Bearer header cannot be constructed. Unlike the BASIC/CUSTOM handlers, it looks up the specific key "token" rather than the first map entry, so any other key name yields this error.

Source

Thrown at src/pkg/p2p/preheat/provider/auth/token_handler.go:40

// TokenAuthHandler handles the OAuth auth mode.
type TokenAuthHandler struct {
	*BaseHandler
}

// Mode implements @Handler.Mode
func (t *TokenAuthHandler) Mode() string {
	return AuthModeOAuth
}

// Authorize implements @Handler.Authorize
func (t *TokenAuthHandler) Authorize(req *http.Request, cred *Credential) error {
	if err := t.BaseHandler.Authorize(req, cred); err != nil {
		return err
	}

	if _, ok := cred.Data["token"]; !ok {
		return errors.New("missing OAuth token")
	}

	authData := fmt.Sprintf("%s %s", "Bearer", cred.Data["token"])
	req.Header.Set("Authorization", authData)

	return nil
}

View on GitHub (pinned to 7b2fd08cc5)

Solutions

  1. Re-save the instance with the token under exactly the "token" key: {"auth_mode": "OAUTH", "auth_info": {"token": "<bearer-token>"}}.
  2. After rotating an expired token, PUT the instance again with the same key.
  3. Re-run the policy execution once the instance credential is fixed.

Example fix

# before
curl -X POST https://harbor/api/v2.0/p2p/preheat/instances -d '{"name": "dfly", "provider": "dragonfly", "endpoint": "https://dfly.example.com", "auth_mode": "OAUTH", "auth_info": {"access_token": "eyJ..."}}'
# after
curl -X POST https://harbor/api/v2.0/p2p/preheat/instances -d '{"name": "dfly", "provider": "dragonfly", "endpoint": "https://dfly.example.com", "auth_mode": "OAUTH", "auth_info": {"token": "eyJ..."}}'
Defensive patterns

Strategy: validation

Validate before calling

function validateOAuthAuthInfo(authInfo) {
  if (!authInfo || typeof authInfo.token !== 'string' || authInfo.token.length === 0)
    throw new Error("OAUTH auth requires a 'token' key");
}

Type guard

function isOAuthCredValid(cred) {
  return cred != null && cred.Data != null && typeof cred.Data['token'] === 'string' && cred.Data['token'].length > 0;
}

Try / catch

On 'missing OAuth token', PUT the instance with auth_info {"token": "<bearer>"} (exact key), then create a new policy execution; no point retrying the failed one.

Prevention

When it happens

Trigger: A preheat instance with auth_mode "OAUTH" whose auth_info lacks a "token" entry — e.g. {"access_token": "..."} or {"Authorization": "..."} or an empty map; any policy execution against the instance fails on its first outbound authorized request.

Common situations: Instance payloads authored with a different token key name; tokens rotated out and auth_info emptied during update; copy-paste from provider docs that use "bearer"/"access_token" field names; expired-token flows where automation rewrites auth_info minus the key.

Related errors


AI-assisted analysis of goharbor/harbor@7b2fd08cc5 (2026-08-16). Data as JSON: /api/errors/f777c2b2ab030364. Report an issue: GitHub.