vxcontrol/pentagi · error
bearer scheme must be used
Error message
bearer scheme must be used
What it means
tryProtoTokenAuthentication in backend/pkg/server/auth/auth_middleware.go rejects an Authorization header that is present but does not start with the exact prefix "Bearer ". The middleware only accepts bearer-token authentication for programmatic API access; any other auth scheme (Basic, raw token, lowercase "bearer") is skipped so other auth paths can be tried, and this error records why. It is a request-shape error, not a token-validity error.
Source
Thrown at backend/pkg/server/auth/auth_middleware.go:203
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 {
return authResultFail, errors.New("token is invalid")
}
// check token status and get privileges through cacheView on GitHub (pinned to ea665308ba)
Solutions
- Set the header exactly to `Authorization: Bearer <api-token>` (capital B, one space).
- If using curl, use `-H "Authorization: Bearer $TOKEN"` instead of `-u` or a bare token header.
- If your client library has an auth helper (e.g. axios AuthInterceptor with token type 'Bearer'), configure it rather than writing the header manually.
- If you intended cookie/session auth, remove the Authorization header so the middleware falls through to session authentication.
Example fix
// before
req.Header.Set("Authorization", apiKey)
// after
req.Header.Set("Authorization", "Bearer "+apiKey) Defensive patterns
Strategy: validation
Validate before calling
const auth = headers["Authorization"];
if (auth !== undefined && !auth.startsWith("Bearer ")) {
throw new Error("Authorization header must use the Bearer scheme");
} Type guard
function isBearerHeader(v: string | undefined): v is string {
return typeof v === "string" && v.startsWith("Bearer ");
} Try / catch
try {
const res = await api.call();
} catch (e) {
if (is401(e) && /bearer scheme/i.test(e.message)) {
fixAuthorizationHeader();
}
throw e;
} Prevention
- Always build the header via an auth helper that emits "Bearer <token>".
- Never hand-concatenate the Authorization value without the scheme constant.
- Add an integration test asserting the exact header string sent.
When it happens
Trigger: Sending an Authorization header whose value does not begin with "Bearer " (case-sensitive, with a single space), e.g. `Authorization: Basic ...`, `Authorization: bearer abc123`, or `Authorization: <raw-token>` with no scheme at all, on an endpoint guarded by this middleware.
Common situations: Copy-pasting a token without the scheme; HTTP clients that auto-attach Basic auth; hand-rolled curl calls omitting the word Bearer; proxy or SDK that lowercases the scheme; using a session cookie flow expectation against the token endpoint.
Related errors
- token can't be empty
- token validation disabled with default salt
- token is invalid
- token not found in database
- token has been revoked
AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01).
Data as JSON: /api/errors/c1085e2517d3ff27.
Report an issue: GitHub.