#12843·authelia

Successful 1FA against an already-responded OIDC consent flow tells the user "Incorrect username or password"

Author: cwfitzgeraldCreated Aug 23, 2026Updated Sep 12, 2026
Labelspriority/4/normaltype/featurestatus/needs-triage

Version

v4.39.20

Deployment Method

Docker

Reverse Proxy

Caddy

Reverse Proxy Version

2.11.4

Description

Thank you for the work on this project!

A user who submits correct credentials against a stale flow_id is told their username or password is wrong. The password check has already succeeded when the portal displays that message. This was hit by a family member who had their password manager automatically save the URL with the flow_id information in it. It would be nice to:

  • Have this report a dedicated error
  • After that report, redirect to an auth page without a flow_id, to prevent "looping".
LLM Dissection of the Issue:

Server side, handleFlowResponseOpenIDConnectNoSubflow replies with messageAuthenticationFailed when the consent session named by flow_id has already been responded to — internal/handlers/response.go:206:

go
if consent.Responded() {
    ctx.SetJSONError(messageAuthenticationFailed)
    ...
    Error("Failed to process consent session as it has already been responded to")

    return
}

Client side, the message is replaced rather than displayed. web/src/views/LoginPortal/FirstFactor/FirstFactorForm.tsx:142 catches every rejection from postFirstFactor and renders one fixed string:

typescript
} catch (err) {
    console.error(err);
    createErrorNotification(translate("Incorrect username or password"));

So the server reports a credential failure, and the frontend narrows it to a specific claim about the username and the password. Both were correct.

FirstFactorPasswordPOST reaches this branch only after authentication succeeds. It sets successful = true, records a successful attempt with the regulator, saves the session, and sets the session cookie, then calls handleFlowResponse (handler_firstfactor_password.go:157). The trace log shows Successful 1FA authentication attempt made by user one line before the error, and Timing Attack Delay successful: true one line after.

Call path from the stack in the log:

handler_firstfactor_password.go:157  FirstFactorPasswordPOST
response.go:151                      handleFlowResponse
response.go:164                      handleFlowResponseOpenIDConnect
response.go:210                      handleFlowResponseOpenIDConnectNoSubflow

A stale bookmark of the portal URL reaches this branch, because the portal URL carries flow_id as a query parameter.

Reproduction

  1. Register an OIDC client. Any authorization_policy and any consent_mode reproduce the issue.
  2. Sign in through that client. Record the flow_id query parameter from the portal URL.
  3. Wait for the consent session to expire. The stored expires_at is 10 minutes after requested_at.
  4. Open https://auth.example.com/?flow=openid_connect&flow_id=<recorded id> directly, without passing through /api/oidc/authorization.
  5. Submit correct credentials.

The portal displays "Incorrect username or password". POST /api/firstfactor returns HTTP 200. The session cookie is set and the user is authenticated.

Expectations

The portal reports that the flow is invalid, distinct from a credential failure, and indicates that login was successful.

Configuration (Authelia)

yaml
# The relevant fields only. The branch is reached for any registered client.
identity_providers:
  oidc:
    clients:
      - client_id: 'app'
        client_name: 'app'
        client_secret: '...'
        public: false
        authorization_policy: 'one_factor'
        consent_mode: 'implicit'
        redirect_uris:
          - 'https://app.example.com/callback'
        scopes: ['openid', 'email', 'profile']

Build Information

bash
Last Tag: v4.39.20
State: tagged clean
Branch: v4.39.20
Commit: 1b524f7f4bbf7b5637f4c6b98f4f66fd4b4aed91
Build Number: 55433
Build OS: linux
Build Arch: amd64
Build Compiler: gc
Build Date: Tue, 26 May 2026 20:16:15 +1000
Development: false
Extra:

Go:
    Version: go1.26.3
    Module Path: github.com/authelia/authelia/v4
    Executable Path: github.com/authelia/authelia/v4/cmd/authelia

Logs (Authelia)

bash
{"caller":{"File":"github.com/authelia/authelia/v4/internal/utils/crypto.go","Line":363,"Name":"NewX509CertPoolWithFactory"},"level":"trace","msg":"Starting scan of directory  for certificates","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/oidc/store.go","Line":53,"Name":"NewMemoryClientStore"},"level":"debug","msg":"Registering OpenID Connect 1.0 client with client id 'webtrees' and policy 'webtrees_2fa_admins'","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/oidc/store.go","Line":53,"Name":"NewMemoryClientStore"},"level":"debug","msg":"Registering OpenID Connect 1.0 client with client id 'beszel' and policy 'beszel_admins_only'","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/startup.go","Line":63,"Name":"doStartupCheck"},"level":"trace","msg":"Performing Startup Check","provider":"storage","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/storage/sql_provider.go","Line":417,"Name":"(*SQLProvider).StartupCheck"},"level":"info","msg":"Storage schema is being checked for updates","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/storage/sql_provider.go","Line":435,"Name":"(*SQLProvider).StartupCheck"},"level":"info","msg":"Storage schema is already up to date","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/startup.go","Line":108,"Name":"doStartupCheck"},"level":"trace","msg":"Startup Check Completed Successfully","provider":"storage","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/startup.go","Line":63,"Name":"doStartupCheck"},"level":"trace","msg":"Performing Startup Check","provider":"session","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/startup.go","Line":108,"Name":"doStartupCheck"},"level":"trace","msg":"Startup Check Completed Successfully","provider":"session","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/startup.go","Line":63,"Name":"doStartupCheck"},"level":"trace","msg":"Performing Startup Check","provider":"user","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/startup.go","Line":108,"Name":"doStartupCheck"},"level":"trace","msg":"Startup Check Completed Successfully","provider":"user","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/startup.go","Line":63,"Name":"doStartupCheck"},"level":"trace","msg":"Performing Startup Check","provider":"notification","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/startup.go","Line":108,"Name":"doStartupCheck"},"level":"trace","msg":"Startup Check Completed Successfully","provider":"notification","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/startup.go","Line":63,"Name":"doStartupCheck"},"level":"trace","msg":"Performing Startup Check","provider":"ntp","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/startup.go","Line":108,"Name":"doStartupCheck"},"level":"trace","msg":"Startup Check Completed Successfully","provider":"ntp","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/startup.go","Line":63,"Name":"doStartupCheck"},"level":"trace","msg":"Performing Startup Check","provider":"expressions","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/startup.go","Line":108,"Name":"doStartupCheck"},"level":"trace","msg":"Startup Check Completed Successfully","provider":"expressions","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/startup.go","Line":63,"Name":"doStartupCheck"},"level":"trace","msg":"Performing Startup Check","provider":"webauthn-metadata","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/startup.go","Line":50,"Name":"(*Providers).StartupChecks"},"level":"debug","msg":"webauthn-metadata provider: startup check skipped as it is disabled","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/spf13/[email protected]/command.go","Line":1148,"Name":"(*Command).ExecuteC"},"level":"trace","msg":"Starting Services","time":"2026-08-23T18:32:03-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/commands/root.go","Line":103,"Name":"(*CmdCtx).RootRunE"},"level":"info","msg":"Startup complete","time":"2026-08-23T18:32:04-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/service/server.go","Line":95,"Name":"(*Server).Run"},"level":"info","msg":"Listening for non-TLS connections on '[::]:9091' path '/'","server":"main","service":"server","time":"2026-08-23T18:32:04-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/service/file_watcher.go","Line":121,"Name":"(*FileWatcher).Run"},"file":"/config/users_database.yml","level":"info","msg":"Watching file for changes","service":"watcher","time":"2026-08-23T18:32:04-04:00","watcher":"users"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"HEAD","msg":"Request hit","path":"/api/health","remote_ip":"::1","time":"2026-08-23T18:32:08-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"HEAD","msg":"Replied (status=200)","path":"/api/health","remote_ip":"::1","time":"2026-08-23T18:32:08-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"HEAD","msg":"Request hit","path":"/api/health","remote_ip":"::1","time":"2026-08-23T18:32:38-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"HEAD","msg":"Replied (status=200)","path":"/api/health","remote_ip":"::1","time":"2026-08-23T18:32:38-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"HEAD","msg":"Request hit","path":"/api/health","remote_ip":"::1","time":"2026-08-23T18:33:09-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"HEAD","msg":"Replied (status=200)","path":"/api/health","remote_ip":"::1","time":"2026-08-23T18:33:09-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Request hit","path":"/","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Replied (status=200)","path":"/","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Request hit","path":"/static/css/index.Dny_JsW-.css","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Replied (status=304)","path":"/static/css/index.Dny_JsW-.css","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Request hit","path":"/static/js/index.CXslS62G.js","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Replied (status=304)","path":"/static/js/index.CXslS62G.js","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Request hit","path":"/locales/en/settings.json","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Replied (status=304)","path":"/locales/en/settings.json","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Request hit","path":"/locales/en-US/consent.json","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Replied (status=200)","path":"/locales/en-US/consent.json","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Request hit","path":"/locales/en-US/settings.json","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Replied (status=200)","path":"/locales/en-US/settings.json","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Request hit","path":"/locales/en/portal.json","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Replied (status=304)","path":"/locales/en/portal.json","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Request hit","path":"/locales/en/consent.json","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Replied (status=304)","path":"/locales/en/consent.json","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Request hit","path":"/locales/en-US/portal.json","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Replied (status=200)","path":"/locales/en-US/portal.json","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Request hit","path":"/api/state","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Replied (status=200)","path":"/api/state","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Request hit","path":"/static/js/portal.FirstFactorForm.5Gd6DmSP.js","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Replied (status=304)","path":"/static/js/portal.FirstFactorForm.5Gd6DmSP.js","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Request hit","path":"/static/js/mui.VisibilityOff.Dutj1hF9.js","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Replied (status=304)","path":"/static/js/mui.VisibilityOff.Dutj1hF9.js","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Request hit","path":"/static/js/mui.TextField.BfBIdloI.js","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Replied (status=304)","path":"/static/js/mui.TextField.BfBIdloI.js","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Request hit","path":"/static/js/constants.constants.C_X5TlRH.js","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Replied (status=304)","path":"/static/js/constants.constants.C_X5TlRH.js","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":12,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Request hit","path":"/static/js/services.Password.CtBaoSU7.js","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"}
{"caller":{"File":"github.com/authelia/authelia/v4/internal/middlewares/log_request.go","Line":16,"Name":"handlerMain.LogRequest.func42"},"level":"trace","method":"GET","msg":"Replied (status=304)","path":"/static/js/services.Password.CtBaoSU7.js","remote_ip":"192.0.2.10","time":"2026-08-23T18:33:30-04:00"