micro/go-micro · error

missing token

Error message

missing token

What it means

When Options.Auth is configured, invokeTool requires every incoming HTTP request to carry a Bearer token in the Authorization header. A request with no token is rejected with HTTP 401 Unauthorized, an OTel span attribute AttrAuthDeniedReason="missing token", and an audit record with Allowed=false.

Source

Thrown at gateway/mcp/mcp.go:786

			return nil, "", false, errResponseWritten
		}
	}

	// Generate trace ID for this call
	traceID := uuid.New().String()

	// Start OTel span (noop if TraceProvider is nil)
	ctx, span := s.startToolSpan(r.Context(), toolName, "http", traceID)
	defer span.End()

	// Authenticate and authorize
	var account *auth.Account
	if s.opts.Auth != nil {
		token := r.Header.Get("Authorization")
		token = strings.TrimPrefix(token, "Bearer ")
		if token == "" {
			span.SetAttributes(attribute.Bool(AttrAuthAllowed, false), attribute.String(AttrAuthDeniedReason, "missing token"))
			setSpanError(span, fmt.Errorf("missing token"))
			s.audit(AuditRecord{TraceID: traceID, Timestamp: time.Now(), Tool: toolName, Allowed: false, DeniedReason: "missing token"})
			return nil, traceID, false, &toolError{status: http.StatusUnauthorized, message: "Unauthorized"}
		}
		acc, err := s.opts.Auth.Inspect(token)
		if err != nil {
			span.SetAttributes(attribute.Bool(AttrAuthAllowed, false), attribute.String(AttrAuthDeniedReason, "invalid token"))
			setSpanError(span, fmt.Errorf("invalid token"))
			s.audit(AuditRecord{TraceID: traceID, Timestamp: time.Now(), Tool: toolName, Allowed: false, DeniedReason: "invalid token"})
			return nil, traceID, false, &toolError{status: http.StatusUnauthorized, message: "Unauthorized"}
		}
		account = acc
		span.SetAttributes(attribute.String(AttrAccountID, account.ID))

		// Check per-tool scopes
		if len(tool.Scopes) > 0 {
			span.SetAttributes(attribute.StringSlice(AttrScopesRequired, tool.Scopes))
			if !hasScope(account.Scopes, tool.Scopes) {
				span.SetAttributes(attribute.Bool(AttrAuthAllowed, false), attribute.String(AttrAuthDeniedReason, "insufficient scopes"))

View on GitHub (pinned to 24529f1404)

Solutions

  1. Send "Authorization: Bearer <valid-token>" on every request to the MCP endpoint.
  2. Verify no reverse proxy/ingress strips the Authorization header before it reaches the gateway.
  3. Obtain a token first from your auth provider (login/service account) and refresh it when expired.
  4. If the endpoint should be public, construct the server with Auth nil so token enforcement is disabled.

Example fix

// before
req, _ := http.NewRequest("POST", mcpURL, body)
// after
req, _ := http.NewRequest("POST", mcpURL, body)
req.Header.Set("Authorization", "Bearer "+token)
Defensive patterns

Strategy: try-catch

Validate before calling

token := strings.TrimPrefix(req.Header.Get("Authorization"), "Bearer ")
if token == "" {
    return errors.New("request must carry an Authorization: Bearer <token> header when Auth is configured")
}

Type guard

func hasBearerToken(h http.Header) (string, bool) {
    const p = "Bearer "
    v := h.Get("Authorization")
    if len(v) > len(p) && v[:len(p)] == p {
        return v[len(p):], true
    }
    return "", false
}

Try / catch

resp, err := http.DefaultClient.Do(req)
if err != nil || resp.StatusCode == http.StatusUnauthorized {
    // refresh/obtain token, re-attach Authorization header, retry once
}

Prevention

When it happens

Trigger: A client calls an MCP tool over the SSE/HTTP transport while Auth is set, but sends no Authorization header or sends "Authorization: Bearer" with an empty token — invokeTool returns the 401 toolError before Inspect is called.

Common situations: Client not configured to attach credentials; a proxy or gateway strips the Authorization header; frontend calls the MCP endpoint without logging in; curl tests omit -H "Authorization: Bearer <token>"; requests made from server-side code that never forwarded the user token.

Related errors


AI-assisted analysis of micro/go-micro@24529f1404 (2026-09-01). Data as JSON: /api/errors/a81ffa0edbc6784c. Report an issue: GitHub.