AUTOMATIC1111/stable-diffusion-webui · error · HTTPException

Incorrect username or password

Error message

Incorrect username or password

What it means

HTTP 401 raised by the API's HTTP Basic auth handler when the request's username is not a key in self.credentials or compare_digest fails on the password. This only applies when the server was started with --api-auth user:pass[,user2:pass2]; the FastAPI route dependency HTTPBasic collects the credentials and every API route added through add_api_route requires them.

Source

Thrown at modules/api/api.py:284

        if not img2img_script_runner.scripts:
            img2img_script_runner.initialize_scripts(True)
        if not self.default_script_arg_img2img:
            self.default_script_arg_img2img = self.init_default_script_args(img2img_script_runner)



    def add_api_route(self, path: str, endpoint, **kwargs):
        if shared.cmd_opts.api_auth:
            return self.app.add_api_route(path, endpoint, dependencies=[Depends(self.auth)], **kwargs)
        return self.app.add_api_route(path, endpoint, **kwargs)

    def auth(self, credentials: HTTPBasicCredentials = Depends(HTTPBasic())):
        if credentials.username in self.credentials:
            if compare_digest(credentials.password, self.credentials[credentials.username]):
                return True

        raise HTTPException(status_code=401, detail="Incorrect username or password", headers={"WWW-Authenticate": "Basic"})

    def get_selectable_script(self, script_name, script_runner):
        if script_name is None or script_name == "":
            return None, None

        script_idx = script_name_to_index(script_name, script_runner.selectable_scripts)
        script = script_runner.selectable_scripts[script_idx]
        return script, script_idx

    def get_scripts_list(self):
        t2ilist = [script.name for script in scripts.scripts_txt2img.scripts if script.name is not None]
        i2ilist = [script.name for script in scripts.scripts_img2img.scripts if script.name is not None]

        return models.ScriptsList(txt2img=t2ilist, img2img=i2ilist)

    def get_script_info(self):
        res = []

View on GitHub (pinned to 82a973c043)

Solutions

  1. Send HTTP Basic auth: requests.post(url, auth=('user','pass'), ...) with exactly the pair passed to --api-auth
  2. Verify the server command line contains --api-auth user:pass and restart if it was changed
  3. If behind a reverse proxy, confirm it forwards the Authorization header
  4. Percent-encode special characters in passwords embedded in URLs, or pass auth via the client library

Example fix

# before
requests.post('http://127.0.0.1:7860/sdapi/v1/txt2img', json=payload)  # 401

# after
requests.post('http://127.0.0.1:7860/sdapi/v1/txt2img', json=payload, auth=('user','pass'))
Defensive patterns

Strategy: try-catch

Validate before calling

# client: verify auth works before heavy calls
probe = requests.get(f'{base}/sdapi/v1/cmd-flags', auth=(user, pw))
if probe.status_code == 401:
    raise PermissionError('bad api credentials; check --api-auth user:pass on server')

Try / catch

resp = requests.post(url, json=payload, auth=(user, pw))
if resp.status_code == 401:
    raise PermissionError('Incorrect username or password: verify --api-auth pairs and header forwarding')

Prevention

When it happens

Trigger: Any /sdapi/v1/* request without an Authorization: Basic header, with a wrong username, wrong password, or a user not listed in --api-auth; also common when a client sends a Bearer token or api key in another header instead of Basic auth.

Common situations: Credentials rotated but the client cached old ones; colon missing in --api-auth so parsing yields different users; proxies (nginx/traefik) stripping the Authorization header; clients URL-embedding user:pass incorrectly (special chars like @ needing percent-encoding).

Related errors


AI-assisted analysis of AUTOMATIC1111/stable-diffusion-webui@82a973c043 (2026-08-14). Data as JSON: /api/errors/24a60a4854092aed. Report an issue: GitHub.