vxcontrol/pentagi · error

token required

Error message

token required

What it means

tryProtoTokenAuthentication inspects the Authorization header for a Bearer API token. When the header is entirely absent the middleware returns authResultSkip with 'token required', meaning this authentication method does not apply and other methods (e.g. session cookie) are attempted. If no method succeeds, the request ends up unauthorized.

Source

Thrown at backend/pkg/server/auth/auth_middleware.go:199

	c.Set("rid", rid.(uint64))
	c.Set("exp", exp.(int64))
	c.Set("gtm", gtm.(int64))
	c.Set("tid", tid.(string))
	c.Set("uname", uname.(string))

	if slices.Contains(prms, PrivilegeAutomation) {
		c.Set("cpt", "automation")
	}

	return authResultOk, nil
}

const PrivilegeAutomation = "pentagi.automation"

func (p *AuthMiddleware) tryProtoTokenAuthentication(c *gin.Context) (authResult, error) {
	authHeader := c.Request.Header.Get("Authorization")
	if authHeader == "" {
		return authResultSkip, errors.New("token required")
	}

	if !strings.HasPrefix(authHeader, "Bearer ") {
		return authResultSkip, errors.New("bearer scheme must be used")
	}
	token := authHeader[7:]
	if token == "" {
		return authResultSkip, errors.New("token can't be empty")
	}

	// skip validation if using default salt (for backward compatibility)
	if p.globalSalt == "" || p.globalSalt == "salt" {
		return authResultSkip, errors.New("token validation disabled with default salt")
	}

	// try to validate as API token first (new format with JWT signing key)
	apiClaims, apiErr := ValidateAPIToken(token, p.globalSalt)
	if apiErr != nil {

View on GitHub (pinned to ea665308ba)

Solutions

  1. Add the header Authorization: Bearer <your-api-token> to the request
  2. Generate an API token in the settings UI if you do not have one
  3. If a proxy sits in front of the API, verify it does not strip the Authorization header

Example fix

// before
curl https://localhost:8443/api/v1/flows
// after
curl -H 'Authorization: Bearer <token>' https://localhost:8443/api/v1/flows
Defensive patterns

Strategy: validation

Validate before calling

if (!localStorage.getItem('apiToken')) throw new Error('Configure an API token before calling the API');
// and always attach it:
headers: { Authorization: `Bearer ${localStorage.getItem('apiToken')}` }

Type guard

const hasBearer = (h: Record<string,string>): boolean =>
  typeof h.Authorization === 'string' && h.Authorization.startsWith('Bearer ') && h.Authorization.length > 7;

Try / catch

try {
  const res = await api.call();
} catch (e) {
  if (e.response?.status === 401) {
    // no/invalid token: prompt user to configure an API token
    promptForTokenSetup();
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling an API endpoint programmatically (curl, scripts, CI) without any Authorization header; removing the header accidentally in an HTTP client config; browser requests that dropped cookies AND carried no bearer token, leaving no auth method available.

Common situations: Forgetting to pass -H 'Authorization: Bearer <token>' in curl; API client library configured without default auth headers; reverse proxy stripping the Authorization header; automation tokens not yet generated in settings.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/6c16d572d4ec08be. Report an issue: GitHub.