tiangolo/fastapi · error · HTTPException
Inactive user
Error message
Inactive user
What it means
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.
Source
Thrown at docs_src/security/tutorial003_an_py310.py:73
return user
async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
user = fake_decode_token(token)
if not user:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Not authenticated",
headers={"WWW-Authenticate": "Bearer"},
)
return user
async def get_current_active_user(
current_user: Annotated[User, Depends(get_current_user)],
):
if current_user.disabled:
raise HTTPException(status_code=400, detail="Inactive user")
return current_user
@app.post("/token")
async def login(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]):
user_dict = fake_users_db.get(form_data.username)
if not user_dict:
raise HTTPException(status_code=400, detail="Incorrect username or password")
user = UserInDB(**user_dict)
hashed_password = fake_hash_password(form_data.password)
if not hashed_password == user.hashed_password:
raise HTTPException(status_code=400, detail="Incorrect username or password")
return {"access_token": user.username, "token_type": "bearer"}
@app.get("/users/me")
async def read_users_me(View on GitHub (pinned to 42a41db11f)
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.
Example fix
# before Authorization: Bearer alice # disabled: True -> 400 # after Authorization: Bearer johndoe # disabled: False -> 200
Defensive patterns
Strategy: try-catch
Validate before calling
None
Type guard
def is_inactive(resp) -> bool:
return getattr(resp, 'status_code', None) == 400 and resp.json().get('detail') == 'Inactive user' Try / catch
try:
me = client.get('/users/me', headers=auth_header(token))
me.raise_for_status()
except httpx.HTTPStatusError as e:
if e.response.status_code == 400 and e.response.json().get('detail') == 'Inactive user':
prompt_reactivation() # do not retry with the same token
raise Prevention
- 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.
When it happens
Trigger: `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.
Common situations: Admin-deactivated accounts; users in a suspended state; the `disabled` flag not flipped back after reactivation; seeding test users with the wrong flag.
Related errors
AI-assisted analysis of tiangolo/fastapi@42a41db11f (2026-08-04).
Data as JSON: /data/errors/f4558192af60395d.json.
Report an issue: GitHub.