{"record":{"id":"5bcc60dec9c3314a","repo":"aio-libs/aiohttp","slug":"digest-auth-error-unsupported-hash-algorithm-al","errorCode":null,"errorMessage":"Digest auth error: Unsupported hash algorithm: {algorithm}. Supported algorithms: {', '.join(SUPPORTED_ALGORITHMS)}","messagePattern":"Digest auth error: Unsupported hash algorithm: (.+?)\\. Supported algorithms: (.+?)","errorType":"exception","errorClass":"ClientError","httpStatus":null,"severity":"error","filePath":"aiohttp/client_middleware_digest_auth.py","lineNumber":293,"sourceCode":"        path = URL(url).raw_path_qs\n\n        # Process QoP\n        qop = \"\"\n        qop_bytes = b\"\"\n        if qop_raw:\n            valid_qops = {\"auth\", \"auth-int\"}.intersection(\n                {q.strip() for q in qop_raw.split(\",\") if q.strip()}\n            )\n            if not valid_qops:\n                raise ClientError(\n                    f\"Digest auth error: Unsupported Quality of Protection (qop) value(s): {qop_raw}\"\n                )\n\n            qop = \"auth-int\" if \"auth-int\" in valid_qops else \"auth\"\n            qop_bytes = qop.encode(\"utf-8\")\n\n        if algorithm not in DigestFunctions:\n            raise ClientError(\n                f\"Digest auth error: Unsupported hash algorithm: {algorithm}. \"\n                f\"Supported algorithms: {', '.join(SUPPORTED_ALGORITHMS)}\"\n            )\n        hash_fn: Final = DigestFunctions[algorithm]\n\n        def H(x: bytes) -> bytes:\n            \"\"\"RFC 7616 Section 3: Hash function H(data) = hex(hash(data)).\"\"\"\n            return hash_fn(x).hexdigest().encode()\n\n        def KD(s: bytes, d: bytes) -> bytes:\n            \"\"\"RFC 7616 Section 3: KD(secret, data) = H(concat(secret, \":\", data)).\"\"\"\n            return H(b\":\".join((s, d)))\n\n        # Calculate A1 and A2\n        A1 = b\":\".join((self._login_bytes, realm_bytes, self._password_bytes))\n        A2 = f\"{method.upper()}:{path}\".encode()\n        if qop == \"auth-int\":\n            if isinstance(body, Payload):  # will always be empty bytes unless Payload","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/client_middleware_digest_auth.py#L275-L311","documentation":"Raised when the Digest challenge's 'algorithm' directive (upper-cased) is not in aiohttp's supported set: MD5, MD5-SESS, SHA, SHA-SESS, SHA256, SHA-256, SHA512, SHA-512 and their -SESS variants. If 'algorithm' is absent the default is MD5; this error only fires when an explicit unsupported value is supplied. The error message lists the supported algorithms for quick diagnosis.","triggerScenarios":"Server sends 'algorithm=BCRYPT' or any token not in DigestFunctions. After upper-casing, the 'algorithm not in DigestFunctions' check in _encode() fails and raises ClientError, including the supported list in the message.","commonSituations":"Server advertising a modern/non-standard algorithm aiohttp has not implemented (e.g. 'SHA3-256', 'argon2'); case or dash variant mismatch (note aiohttp normalizes case but expects exact token spelling like 'SHA-256'); legacy server using a custom scheme name.","solutions":["Read the error message — it lists exactly which algorithms are supported.","Change the server to offer one of: MD5, SHA-256, SHA-512 (prefer SHA-256 or stronger; MD5/SHA are weak).","Verify the token spelling matches a supported key exactly (e.g. 'SHA-256' with the dash, not 'SHA256_256').","If the server requires an unsupported algorithm, switch to a Digest library that supports it or request the feature upstream."],"exampleFix":"# before — server: algorithm=SHA3-256\nawait session.get(url)  # ClientError: Unsupported hash algorithm: SHA3-256\n\n# after — server uses a supported algorithm\n# WWW-Authenticate: Digest realm=\"x\", nonce=\"...\", algorithm=SHA-256","handlingStrategy":"validation","validationCode":"SUPPORTED = {'MD5','MD5-SESS','SHA','SHA-SESS','SHA256','SHA-256','SHA256-SESS',\n             'SHA-256-SESS','SHA512','SHA-512','SHA512-SESS','SHA-512-SESS'}\n\ndef algorithm_supported(www_authenticate: str) -> bool:\n    import re\n    m = re.search(r'algorithm=([A-Za-z0-9-]+)', www_authenticate)\n    if not m:\n        return True  # default MD5\n    return m.group(1).upper() in SUPPORTED","typeGuard":"def is_supported_digest_algorithm(algorithm: str) -> bool:\n    return algorithm.upper() in {\n        'MD5','MD5-SESS','SHA','SHA-SESS','SHA256','SHA-256',\n        'SHA256-SESS','SHA-256-SESS','SHA512','SHA-512','SHA512-SESS','SHA-512-SESS'}","tryCatchPattern":"from aiohttp import ClientError\n\ntry:\n    resp = await session.get(url)\nexcept ClientError as e:\n    if 'Unsupported hash algorithm' in str(e):\n        # parse the supported list from the message and reconfigure server\n        log.error('Digest algorithm unsupported. %s', e)\n    raise","preventionTips":["Prefer SHA-256 for new Digest deployments; MD5/SHA are weak.","Keep the supported-algorithm list in sync with the aiohttp version in use.","Test against the real server's challenge during CI."],"tags":["digest-auth","authentication","http","client-middleware","cryptography"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}