pallets/flask · error · ValueError

'{exc_class_or_code}' is not a recognized HTTP error code. U

Error message

'{exc_class_or_code}' is not a recognized HTTP error code. Use a subclass of HTTPException with that code instead.

What it means

When you register an error handler with an integer code, Flask looks it up in Werkzeug's default_exceptions mapping to find the corresponding HTTPException class. Only standard HTTP error codes with a registered exception class exist there; an unknown integer (like 200, 250, or a custom 4xx) raises this ValueError from _get_exc_class_and_code.

Source

Thrown at src/flask/sansio/scaffold.py:673

    @staticmethod
    def _get_exc_class_and_code(
        exc_class_or_code: type[Exception] | int,
    ) -> tuple[type[Exception], int | None]:
        """Get the exception class being handled. For HTTP status codes
        or ``HTTPException`` subclasses, return both the exception and
        status code.

        :param exc_class_or_code: Any exception class, or an HTTP status
            code as an integer.
        """
        exc_class: type[Exception]

        if isinstance(exc_class_or_code, int):
            try:
                exc_class = default_exceptions[exc_class_or_code]
            except KeyError:
                raise ValueError(
                    f"'{exc_class_or_code}' is not a recognized HTTP"
                    " error code. Use a subclass of HTTPException with"
                    " that code instead."
                ) from None
        else:
            exc_class = exc_class_or_code

        if isinstance(exc_class, Exception):
            raise TypeError(
                f"{exc_class!r} is an instance, not a class. Handlers"
                " can only be registered for Exception classes or HTTP"
                " error codes."
            )

        if not issubclass(exc_class, Exception):
            raise ValueError(
                f"'{exc_class.__name__}' is not a subclass of Exception."
                " Handlers can only be registered for Exception classes"

View on GitHub ↗ (pinned to 6a2f545bfd)

Solutions

  1. Use a recognized HTTP error code (one that has a Werkzeug HTTPException, e.g. 404, 500).
  2. For a custom code, subclass werkzeug.exceptions.HTTPException with code = <n> and register the handler for that class.
  3. For non-error statuses, use an after_request hook instead of an error handler.

Example fix

# before
@app.errorhandler(420)
def handle(e): ...
# after
from werkzeug.exceptions import HTTPException
class EnhanceYourCalm(HTTPException):
    code = 420
    description = 'Enhance your calm.'
@app.errorhandler(EnhanceYourCalm)
def handle(e): ...
Defensive patterns

Strategy: validation

Validate before calling

from werkzeug.exceptions import default_exceptions
code = 404
if code not in default_exceptions:
    raise ValueError(f"{code} is not a standard HTTP error code; register a custom HTTPException subclass instead")
app.register_error_handler(code, handler)

Type guard

from werkzeug.exceptions import default_exceptions
def is_registrable_code(code) -> bool:
    return isinstance(code, int) and code in default_exceptions

Prevention

When it happens

Trigger: @app.errorhandler(code) or app.register_error_handler(code, fn) with an int not in werkzeug.exceptions.default_exceptions — e.g. 200, 302 (non-error), 420, 444, or a proprietary code.

Common situations: Trying to hook non-error statuses (2xx/3xx) with errorhandler; using nginx/Cloudflare-specific codes (444, 520); expecting arbitrary custom status codes to work without defining an exception class.

Related errors


AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31). Data as JSON: /data/errors/c104959419c82ea7.json. Report an issue: GitHub ↗.