gotify/server · error

failed to generate state: %v

Error message

failed to generate state: %v

What it means

LoginHandler calls generateState to create the CSRF/state token for the OIDC flow. If state generation fails (the error is wrapped into the response body), the handler responds with 500 'failed to generate state: <err>'.

Source

Thrown at api/oidc.go:139

//	  required: true
//	  type: string
//	responses:
//	  302:
//	    description: Redirect to OIDC provider
//	  default:
//	    description: Error
//	    schema:
//	        $ref: "#/definitions/Error"
func (a *OIDCAPI) LoginHandler() gin.HandlerFunc {
	return gin.WrapF(func(w http.ResponseWriter, r *http.Request) {
		clientName := r.URL.Query().Get("name")
		if clientName == "" {
			http.Error(w, "invalid client name", http.StatusBadRequest)
			return
		}
		state, err := a.generateState()
		if err != nil {
			http.Error(w, fmt.Sprintf("failed to generate state: %v", err), http.StatusInternalServerError)
			return
		}
		a.pendingSessions.Set(time.Now(), state, &pendingOIDCSession{ClientName: clientName, CreatedAt: time.Now()})
		rp.AuthURLHandler(func() string { return state }, a.Provider, a.promptURLParams()...)(w, r)
	})
}

// swagger:operation GET /auth/oidc/elevate oidc oidcElevate
//
// Start the OIDC flow to elevate an existing client session (browser).
//
// Redirects the user to the OIDC provider's authorization endpoint. After
// successful authentication, the referenced client session is elevated for
// the requested duration.
//
//	---
//	parameters:
//	- name: id

View on GitHub (pinned to 14bfc25627)

Solutions

  1. Inspect the wrapped inner error in the response body to find the root cause
  2. Ensure the runtime has a working crypto/rand source (check entropy availability in the container)
  3. Restart the server/process if the random source is exhausted or broken
  4. Upgrade Go/runtime if entropy-blocking behavior at startup is the issue
Defensive patterns

Strategy: retry

Try / catch

resp, err := http.Get(loginURL)
if resp.StatusCode == 500 {
    body, _ := io.ReadAll(resp.Body)
    if strings.HasPrefix(string(body), "failed to generate state") {
        time.Sleep(time.Second)
        // retry the login request once
    }
}

Prevention

When it happens

Trigger: generateState returning an error — typically failure of its underlying randomness source (crypto/rand read error) during the login request.

Common situations: Degraded system entropy on constrained containers or VMs, or a misconfigured custom randomness source in tests.

Related errors


AI-assisted analysis of gotify/server@14bfc25627 (2026-09-05). Data as JSON: /api/errors/8f025f2a498ba89b. Report an issue: GitHub.