gotify/server · error
failed to elevate session: %v
Error message
failed to elevate session: %v
What it means
handleElevationCallback (api/oidc.go:269) returns HTTP 500 'failed to elevate session: %v' when a.DB.UpdateClientElevatedUntil(client.ID, &elevatedUntil) errors after the client was found and ownership verified. The client lookup succeeded but persisting the new elevated-until timestamp failed.
Source
Thrown at api/oidc.go:269
w.Header().Set("Location", "../../")
w.WriteHeader(http.StatusTemporaryRedirect)
}
return gin.WrapF(rp.CodeExchangeHandler(rp.UserinfoCallback(callback), a.Provider))
}
func (a *OIDCAPI) handleElevationCallback(w http.ResponseWriter, elevate *pendingElevation, user *model.User) {
client, err := a.DB.GetClientByID(elevate.ClientID)
if err != nil {
http.Error(w, fmt.Sprintf("database error: %v", err), http.StatusInternalServerError)
return
}
if client == nil || client.UserID != user.ID {
http.Error(w, "client not found", http.StatusNotFound)
return
}
elevatedUntil := time.Now().Add(time.Duration(elevate.DurationSeconds) * time.Second)
if err := a.DB.UpdateClientElevatedUntil(client.ID, &elevatedUntil); err != nil {
http.Error(w, fmt.Sprintf("failed to elevate session: %v", err), http.StatusInternalServerError)
return
}
// The UI rechecks the authentication when the tab is closed.
w.WriteHeader(http.StatusOK)
w.Header().Add("content-type", "text/html")
io.WriteString(w, `<!DOCTYPE html>
<html lang="en">
<head>
<title>Gotify Session Elevation</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
</head>
<body>
<h1 style="text-align:center">Gotify session elevation successful. Close this tab to continue.</h1>
<script>window.close();</script>
</body>
</html>`)View on GitHub (pinned to 14bfc25627)
Solutions
- Check the wrapped error and database server logs; verify connectivity and that the DB accepts writes
- Confirm the DB user has UPDATE permission on the clients table and migrations are current
- Retry the elevation flow (with a fresh state) once the database is writable
- For SQLite lock errors, ensure no other process holds the DB and consider WAL mode
- Rule out read-only replica routing or disk-space/quota issues
Defensive patterns
Strategy: retry
Validate before calling
// Before the elevation round-trip, verify the DB accepts writes on clients
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()
if err := db.PingContext(ctx); err != nil {
return err
}
// optionally a probe write/transaction to catch read-only replicas early Try / catch
err := db.UpdateClientElevatedUntil(clientID, &elevatedUntil)
if err != nil {
if isTransient(err) { // deadlock, bad conn, timeout, lock
return retryWithBackoff(func() error {
return db.UpdateClientElevatedUntil(clientID, &elevatedUntil)
})
}
return fmt.Errorf("update elevated_until: %w", err)
} Prevention
- Grant the DB user UPDATE privilege on the clients table
- Keep migrations current so the elevated_until column exists
- Enable WAL/busy-timeout for SQLite to avoid lock errors
- Monitor for read-only replica routing and disk-full conditions
- Retry transient write failures with backoff before failing the request
When it happens
Trigger: UpdateClientElevatedUntil fails during the elevation callback: database connection dropped between the read and the write, write timeout, read-only replica/transaction, constraint or schema error, or disk-full on the DB server.
Common situations: Remote Postgres briefly unavailable or failing over; DB user lacking UPDATE privilege on the clients table; migrations missing a column used by the update; SQLite database locked by another process; storage quota exhausted.
Related errors
- database error: %v
- failed to bind user to OIDC identity: %w
- failed to create user: %w
- failed to create client: %v
- issuer claim was empty
AI-assisted analysis of gotify/server@14bfc25627 (2026-09-05).
Data as JSON: /api/errors/3585d6dd318f0d20.
Report an issue: GitHub.