crewAIInc/crewAI · error · HTTPException

Invalid or missing authentication credentials

Error message

Invalid or missing authentication credentials

What it means

Raised by SimpleTokenAuth.authenticate() when the bearer token supplied by the client does not equal the expected token (the scheme's `token` field or the AUTH_TOKEN env var). It is a standard HTTP 401 rejection: the server is configured correctly, but the presented credential is wrong or missing. Comparison is a direct string equality check against the single configured secret.

Source

Thrown at lib/crewai/src/crewai/a2a/auth/server_schemes.py:178

            AuthenticatedUser on successful authentication.

        Raises:
            HTTPException: If authentication fails.
        """
        expected = self._get_expected_token()

        if expected is None:
            logger.warning(
                "Simple token authentication failed",
                extra={"reason": "no_token_configured"},
            )
            raise HTTPException(
                status_code=HTTP_401_UNAUTHORIZED,
                detail="Authentication not configured",
            )

        if token != expected:
            raise HTTPException(
                status_code=HTTP_401_UNAUTHORIZED,
                detail="Invalid or missing authentication credentials",
            )

        return AuthenticatedUser(
            token=token,
            scheme="simple_token",
        )


class EnterpriseTokenAuth(ServerAuthScheme):
    """Enterprise token authentication.

    Validates tokens via the PlusAPI enterprise verification endpoint.
    """

    async def authenticate(self, token: str) -> AuthenticatedUser:
        """Authenticate using enterprise token verification.

View on GitHub (pinned to 754d7323be)

Solutions

  1. Verify the client sends exactly the configured value: header 'Authorization: Bearer <AUTH_TOKEN>' with no extra whitespace or quotes.
  2. Re-check which env the server process actually loaded: print/log whether AUTH_TOKEN or an explicit token field is in effect.
  3. After a rotation, redeploy all clients and all server replicas with the new token.
  4. Strip the token of trailing newlines when reading it from files/CI secrets (token.strip()).

Example fix

# before
response = await client.post(url, headers={"Authorization": f"Bearer {os.environ['TOKEN_FILE_CONTENT}"} })  # raw content may include \n

# after
raw = os.environ["TOKEN_FILE_CONTENT"].strip()
response = await client.post(url, headers={"Authorization": f"Bearer {raw}"})
Defensive patterns

Strategy: validation

Validate before calling

import os

expected = os.environ["AUTH_TOKEN"]
assert supplied_token == expected, "token mismatch before sending request"
headers = {"Authorization": f"Bearer {supplied_token.strip()}"}

Try / catch

try:
    result = await scheme.authenticate(token)
except HTTPException as e:
    if e.status_code == 401:
        # credential problem: log the client identity, never log the token itself
        raise

Prevention

When it happens

Trigger: Any request whose Authorization: Bearer <token> value differs from the configured secret: client sends an old/rotated token, sends 'Bearer' with no value so an empty string is compared, or copies a token from a different environment (dev token against prod server).

Common situations: Token rotation where one side was not updated; trailing whitespace or newline included when copying the secret; client library that prefixes/strips the header differently; multiple replicas configured with different AUTH_TOKEN values.

Understand the failure class

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/37ce1316575a6025. Report an issue: GitHub.