{"record":{"id":"b06931a2f5054117","repo":"aio-libs/aiohttp","slug":"unknown-expect-s","errorCode":null,"errorMessage":"Unknown Expect: %s","messagePattern":"Unknown Expect: (.+?)","errorType":"http","errorClass":"HTTPExpectationFailed","httpStatus":417,"severity":"warning","filePath":"aiohttp/web_urldispatcher.py","lineNumber":305,"sourceCode":"\n    def __repr__(self) -> str:\n        return f\"<MatchInfoError {self._exception.status}: {self._exception.reason}>\"\n\n\nasync def _default_expect_handler(request: Request) -> None:\n    \"\"\"Default handler for Expect header.\n\n    Just send \"100 Continue\" to client.\n    raise HTTPExpectationFailed if value of header is not \"100-continue\"\n    \"\"\"\n    expect = request.headers.get(hdrs.EXPECT, \"\")\n    if request.version == HttpVersion11:\n        if expect.lower() == \"100-continue\":\n            await request.writer.write(b\"HTTP/1.1 100 Continue\\r\\n\\r\\n\")\n            # Reset output_size as we haven't started the main body yet.\n            request.writer.output_size = 0\n        else:\n            raise HTTPExpectationFailed(text=\"Unknown Expect: %s\" % expect)\n\n\nclass Resource(AbstractResource):\n    def __init__(self, *, name: str | None = None) -> None:\n        super().__init__(name=name)\n        self._routes: dict[str, ResourceRoute] = {}\n        self._any_route: ResourceRoute | None = None\n        self._allowed_methods: set[str] = set()\n\n    def add_route(\n        self,\n        method: str,\n        handler: type[AbstractView] | Handler,\n        *,\n        expect_handler: _ExpectHandler | None = None,\n    ) -> \"ResourceRoute\":\n        if route := self._routes.get(method, self._any_route):\n            raise RuntimeError(","sourceCodeStart":287,"sourceCodeEnd":323,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/web_urldispatcher.py#L287-L323","documentation":"The default Expect-header handler (_default_expect_handler) is invoked when a request carries an Expect header. For HTTP/1.1, the only recognized value is '100-continue' (case-insensitive), to which the server responds with an interim 'HTTP/1.1 100 Continue'. Any other Expect value (e.g. a future or custom expectation token) raises HTTPExpectationFailed (HTTP 417), because the server cannot satisfy an unknown expectation and per RFC 7231 must reject the request.","triggerScenarios":"A client sends an HTTP/1.1 request with an Expect header whose value is not '100-continue' — for example 'Expect: 102-processing', a custom token, or a malformed value. The error is raised during request handling, after the request line and headers are parsed and the route is dispatched, when aiohttp invokes the expect_handler.","commonSituations":"Non-compliant or experimental clients; testing tools that inject arbitrary Expect values; a client library that sends a newer expectation token the server does not yet support; proxy chaining that mangles the header.","solutions":["Have the client send only 'Expect: 100-continue' (the RFC-defined expectation) or omit the header.","If a custom expectation is needed, register a custom expect_handler on the route via expect_handler=<async fn> that handles your token.","Return a clear 417 response to the client and document the unsupported expectation."],"exampleFix":"// before (client)\nheaders = {'Expect': '102-processing'}\n// after\nheaders = {'Expect': '100-continue'}  # or omit the header","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"from aiohttp.web_exceptions import HTTPExpectationFailed\n\nasync def handler(request):\n    try:\n        ...\n    except HTTPExpectationFailed:\n        return web.Response(status=417, text='Unsupported Expect header')","preventionTips":["Register a custom expect_handler on routes where clients send non-standard Expect values.","Document to clients that only Expect: 100-continue is supported.","Log the offending Expect value to identify misbehaving clients."],"tags":["http","expect-header","client-error","http-417"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}