{"record":{"id":"cedd5b4956264505","repo":"xtekky/gpt4free","slug":"api-key-has-failed-too-many-times","errorCode":null,"errorMessage":"API key has failed too many times.","messagePattern":"API key has failed too many times\\.","errorType":"exception","errorClass":"MissingAuthError","httpStatus":null,"severity":"error","filePath":"g4f/Provider/needs_auth/Azure.py","lineNumber":141,"sourceCode":"                    \"x-ms-model-mesh-model-name\": model,\n                },\n            ) as session:\n                async with session.post(api_endpoint, data=form, json=data) as response:\n                    data = await response.json()\n                    await raise_for_status(response, data)\n                    async for chunk in save_response_media(\n                        data[\"data\"][0][\"b64_json\"],\n                        prompt,\n                        content_type=f\"image/{output_format.replace('jpg', 'jpeg')}\",\n                    ):\n                        yield chunk\n            return\n        if model in cls.model_extra_body:\n            for key, value in cls.model_extra_body[model].items():\n                kwargs.setdefault(key, value)\n            stream = False\n        if cls.failed.get(model + api_key, 0) >= 3:\n            raise MissingAuthError(f\"API key has failed too many times.\")\n        try:\n            async for chunk in super().create_async_generator(\n                model=model,\n                messages=messages,\n                stream=stream,\n                media=media,\n                api_key=api_key,\n                api_endpoint=api_endpoint,\n                **kwargs,\n            ):\n                yield chunk\n        except MissingAuthError as e:\n            cls.failed[model + api_key] = cls.failed.get(model + api_key, 0) + 1\n            raise MissingAuthError(\n                f\"{e}. Ask for help in the {cls.login_url} Discord server.\"\n            ) from e\n","sourceCodeStart":123,"sourceCodeEnd":158,"githubUrl":"https://github.com/xtekky/gpt4free/blob/973504e1770928ed5fb82f43da528f441ad9ddc3/g4f/Provider/needs_auth/Azure.py#L123-L158","documentation":"The Azure provider keeps a per-(model+api_key) failure counter in cls.failed; after the wrapped base generator raises MissingAuthError three times for the same key, subsequent calls short-circuit with MissingAuthError immediately. It is a circuit breaker: the key is considered dead until the counters reset (new process or cleared dict).","triggerScenarios":"Three consecutive requests with an invalid/expired Azure API key (each failure increments cls.failed[model+api_key]); the fourth call raises before any network I/O. The counter is also incremented in the except MissingAuthError handler after the super() call.","commonSituations":"Azure key rotated/revoked while the long-lived server kept retrying; wrong key in AZURE_API_KEYS from the start; deployment key permissions removed in Azure portal.","solutions":["Fix the underlying credential: update AZURE_API_KEYS (or api_key argument) with a valid key for the deployment.","Restart the process (or clear Azure.failed dict) after replacing the key — the circuit breaker does not auto-reset.","Verify the new key works with a direct curl to the deployment before restarting g4f."],"exampleFix":"# before: key rotated but process still holds failures\n# every request raises MissingAuthError('API key has failed too many times.')\n\n# after: fix env and reset the breaker\nexport AZURE_API_KEYS='{\"default\": \"sk-NEW-VALID-KEY\"}'\n# then restart the app, or in-process:\nAzure.failed.clear()  # g4f.Provider.needs_auth.Azure.failed.clear()","handlingStrategy":"retry","validationCode":"from g4f.Provider.needs_auth import Azure\n\nif Azure.failed.get(model + api_key, 0) >= 3:\n    # circuit open: verify the key out-of-band before resetting\n    Azure.failed.clear()  # only after the key is confirmed valid","typeGuard":"def azure_circuit_open(model: str, api_key: str) -> bool:\n    \"\"\"True when the per-key failure breaker has tripped.\"\"\"\n    return Azure.failed.get(model + api_key, 0) >= 3","tryCatchPattern":"from g4f.errors import MissingAuthError\n\ntry:\n    await Azure.create_async_generator(model=model, messages=messages)\nexcept MissingAuthError as e:\n    if \"failed too many times\" in str(e):\n        # fix the key, then reset the breaker and retry once:\n        os.environ[\"AZURE_API_KEYS\"] = json.dumps({\"default\": new_valid_key})\n        Azure.api_keys = json.loads(os.environ[\"AZURE_API_KEYS\"])\n        Azure.failed.clear()\n        # retry","preventionTips":["Verify Azure keys with a direct deployment call before plugging them into g4f","After rotating keys, restart the process or clear Azure.failed — the breaker never auto-resets","Treat the first MissingAuthError (not the third) as the signal to rotate credentials"],"tags":["api-key","circuit-breaker","azure","authentication"],"backgroundTag":null,"analyzedSha":"973504e1770928ed5fb82f43da528f441ad9ddc3","analyzedAt":"2026-08-14T23:45:32.408Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}