{"id":"f4558192af60395d","repo":"tiangolo/fastapi","slug":"inactive-user","errorCode":null,"errorMessage":"Inactive user","messagePattern":"Inactive user","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"docs_src/security/tutorial003_an_py310.py","lineNumber":73,"sourceCode":"    return user\n\n\nasync def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):\n    user = fake_decode_token(token)\n    if not user:\n        raise HTTPException(\n            status_code=status.HTTP_401_UNAUTHORIZED,\n            detail=\"Not authenticated\",\n            headers={\"WWW-Authenticate\": \"Bearer\"},\n        )\n    return user\n\n\nasync def get_current_active_user(\n    current_user: Annotated[User, Depends(get_current_user)],\n):\n    if current_user.disabled:\n        raise HTTPException(status_code=400, detail=\"Inactive user\")\n    return current_user\n\n\n@app.post(\"/token\")\nasync def login(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]):\n    user_dict = fake_users_db.get(form_data.username)\n    if not user_dict:\n        raise HTTPException(status_code=400, detail=\"Incorrect username or password\")\n    user = UserInDB(**user_dict)\n    hashed_password = fake_hash_password(form_data.password)\n    if not hashed_password == user.hashed_password:\n        raise HTTPException(status_code=400, detail=\"Incorrect username or password\")\n\n    return {\"access_token\": user.username, \"token_type\": \"bearer\"}\n\n\n@app.get(\"/users/me\")\nasync def read_users_me(","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/tiangolo/fastapi/blob/42a41db11f6882807ac3c057b942178d53b97438/docs_src/security/tutorial003_an_py310.py#L55-L91","documentation":"Raised by `get_current_active_user` with HTTP 400 when an authenticated user has `disabled=True`. The user was already resolved by `get_current_user`, so credentials are valid - the account is just turned off. In the sample DB the user `alice` has `disabled: True`, so authenticating as her produces this.","triggerScenarios":"`GET /users/me` (or any route depending on `get_current_active_user`) after authenticating as `alice`, whose record has `disabled: True`. Authenticating as `johndoe` (`disabled: False`) succeeds.","commonSituations":"Admin-deactivated accounts; users in a suspended state; the `disabled` flag not flipped back after reactivation; seeding test users with the wrong flag.","solutions":["Authenticate as a non-disabled user (e.g. `johndoe` in the sample DB).","If you own the DB, set the user's `disabled` field to `False`.","Surface a clear 'account disabled' message to the end user instead of retrying."],"exampleFix":"# before\nAuthorization: Bearer alice   # disabled: True -> 400\n# after\nAuthorization: Bearer johndoe  # disabled: False -> 200","handlingStrategy":"try-catch","validationCode":"None","typeGuard":"def is_inactive(resp) -> bool:\n    return getattr(resp, 'status_code', None) == 400 and resp.json().get('detail') == 'Inactive user'","tryCatchPattern":"try:\n    me = client.get('/users/me', headers=auth_header(token))\n    me.raise_for_status()\nexcept httpx.HTTPStatusError as e:\n    if e.response.status_code == 400 and e.response.json().get('detail') == 'Inactive user':\n        prompt_reactivation()  # do not retry with the same token\n    raise","preventionTips":["Do not retry on 'Inactive user' - the credentials are valid but the account is off.","Keep the disabled flag in sync with your admin tooling.","Give end users a path to reactivate rather than a raw 400."],"tags":["authorization","security","user-management","fastapi"],"analyzedSha":"42a41db11f6882807ac3c057b942178d53b97438","analyzedAt":"2026-08-04T19:23:32.007Z","schemaVersion":2}