locustio/locust · error · LocustBadStatusCode

LocustBadStatusCode

Error message

LocustBadStatusCode

What it means

_verify_status is a hook in FastHttpSession that raises LocustBadStatusCode when the HTTP status code of a response is not in the session's valid_response_codes (by default 2xx). It signals the request will be marked as a failure in Locust statistics.

Source

Thrown at locust/contrib/fasthttp.py:690

    def __init__(self, client_pool: HTTPClientPool | None = None, **kwargs):
        super().__init__(**kwargs)

        if client_pool is not None:
            self.clientpool = client_pool

    def _urlopen(self, request):
        """Override _urlopen() in order to make it use the response_type attribute"""
        client = self.clientpool.get_client(request.url_split)
        resp = client.request(
            request.method, request.url_split.request_uri, body=request.payload, headers=request.headers
        )
        return self.response_type(resp, request=request, sent_request=resp._sent_request)

    def _verify_status(self, status_code, url=None):
        """Hook for subclassing"""
        if status_code not in self.valid_response_codes:
            raise LocustBadStatusCode(url, code=status_code)


class ResponseContextManager(FastResponse):
    """
    A Response class that also acts as a context manager that provides the ability to manually
    control if an HTTP request should be marked as successful or a failure in Locust's statistics

    This class is a subclass of :py:class:`FastResponse <locust.contrib.fasthttp.FastResponse>`
    with two additional methods: :py:meth:`success <locust.contrib.fasthttp.ResponseContextManager.success>`
    and :py:meth:`failure <locust.contrib.fasthttp.ResponseContextManager.failure>`.
    """

    _manual_result = None
    _entered = False

    def __init__(self, response, request_event, request_meta, catch_response: bool):
        # copy data from response to this object (use update to avoid sharing
        # the dict reference, which creates a GC-reference cycle that Python 3.13+

View on GitHub (pinned to f391a716e1)

Solutions

  1. Check the URL and request setup to ensure the expected success status is returned
  2. Adjust valid_response_codes on the FastHttpSession if the status is legitimately acceptable
  3. Handle the response manually with catch_response=True and response.success() to override the default code-based verdict

Example fix

// before
class MySession(FastHttpSession):
    pass
// after
class MySession(FastHttpSession):
    valid_response_codes = [200, 201, 404, 429]
Defensive patterns

Strategy: try-catch

Validate before calling

# check status before relying on default verdict
resp = self.client.get("/api/item")
if resp.status_code not in self.client.valid_response_codes:
    # handle or override with catch_response=True flow

Try / catch

from locust.exception import LocustBadStatusCode
try:
    resp = self.client.get("/api/item")
except LocustBadStatusCode as e:
    self.environment.events.request.fire(...)  # or log and continue

Prevention

When it happens

Trigger: self.client.get()/request() returning a status code outside valid_response_codes; or a custom FastHttpSession subclass whose _verify_status override raises it deliberately.

Common situations: Hitting endpoints that return 3xx redirects not followed, 404s on stale test data, 5xx server errors under load, or misconfigured base_url leading to unexpected responses.

Related errors


AI-assisted analysis of locustio/locust@f391a716e1 (2026-08-29). Data as JSON: /api/errors/3df01d92cc957649. Report an issue: GitHub.