#2877·hanko

Login and registration return 500 when the User-Agent exceeds 255 characters

Author: Erikvl87Created Sep 1, 2026Updated Sep 1, 2026
Labelsbug

Checklist

  • I could not find a solution in the existing issues or docs.
  • I agree to follow this project's Code of Conduct.

Describe the bug

Login and registration return a 500 when the client sends a User-Agent longer than 255 characters, with session.acquire_user_agent on (the default). The password or passcode is verified first, so the visitor answers correctly and then gets "Something went wrong" with no session.

The session insert fails with:

the action failed to handle the request: failed to execute before state hook (state: success): failed to store session: failed to store session: named insert: ERROR: value too long for type character varying(255) (SQLSTATE 22001)

I hit it in production from the Instagram in-app browser on Android, which sends 278 characters:

Mozilla/5.0 (Linux; Android 16; SM-S911B Build/BP4A.251205.006; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/152.0.7977.69 Mobile Safari/537.36 Instagram 445.0.0.45.83 Android (36/16; 480dpi; 1080x2340; samsung; SM-S911B; dm1q; qcom; nl_NL; 1055488490; IABMV/1)

I have not debugged the backend, so the cause below is a guess from reading the source. sessions.user_agent is declared as an unsized fizz string in 20241002113000_create_sessions.up.fizz, which fizz maps to VARCHAR (255) on Postgres (translators/postgres.go), and the header is stored verbatim in hook_issue_session.go. Whether the fix is truncating before the insert, widening the column, or something else is your call.

Reproducing the bug

  1. Run the backend against Postgres with session.acquire_user_agent: true.
  2. Complete a login or a registration from a client sending a User-Agent over 255 characters against the flow API, or open the app in an Instagram or Facebook in-app browser.
  3. The before hook of the success state fails and the request returns 500 technical_error. No session row is written and no token is issued.

I reproduced this locally with the 278-character string above on both password_login and registration. A 111-character User-Agent on the same build succeeds, and so does any login with acquire_user_agent: false.

Logs

bash
POST /login?action=password_login@...  status 500  error technical_error
the action failed to handle the request: failed to execute before state hook (state: success): failed to store session: failed to store session: named insert: ERROR: value too long for type character varying(255) (SQLSTATE 22001)

Configuration

yaml
session:
  acquire_user_agent: true

Hanko Version

v2.7.0

OS Hanko Backend

Linux

OS Version Hanko Backend

Docker Compose, backend on Linux, Postgres. Client: Instagram in-app browser on Android 16.

OS

Other

OS Version

No response

Browser Version

No response

Environment

None

Additional Context

I work around it by trimming the User-Agent to 255 characters in the reverse proxy in front of Hanko. Setting session.acquire_user_agent: false also avoids it, at the cost of the user agent on the profile session list.

audit_logs.meta_user_agent is declared the same way in 20220818111000_create_audit_logs.up.fizz, so the same overflow looks reachable there.