vxcontrol/pentagi · warning

Auth.InvalidAuthorizationState

Auth.InvalidAuthorizationState

Error message

state parameter is required

What it means

Auth.InvalidAuthorizationState is returned when the OAuth callback is missing the 'state' query parameter. The state parameter is the CSRF protection token that must match the HMAC-signed value stored in the state cookie; without it the server cannot correlate the callback to the original login attempt. It is also returned when the state does not match the cookie value (errors logged, nil error passed).

Source

Thrown at backend/pkg/server/services/auth.go:357

// @Router /auth/login-callback [get]
func (s *AuthService) AuthLoginGetCallback(c *gin.Context) {
	code := c.Query("code")
	if code == "" {
		response.Error(c, response.ErrAuthInvalidLoginCallbackRequest, fmt.Errorf("code is required"))
		return
	}

	state, err := c.Request.Cookie(s.stateCookieName())
	if err != nil {
		logger.FromContext(c).WithError(err).Errorf("error getting state from cookie")
		response.Error(c, response.ErrAuthInvalidAuthorizationState, err)
		return
	}

	queryState := c.Query("state")
	if queryState == "" {
		logger.FromContext(c).Errorf("error missing state parameter in OAuth callback")
		response.Error(c, response.ErrAuthInvalidAuthorizationState, fmt.Errorf("state parameter is required"))
		return
	}

	if queryState != state.Value {
		logger.FromContext(c).Errorf("error matching received state to stored one")
		response.Error(c, response.ErrAuthInvalidAuthorizationState, nil)
		return
	}

	stateData, err := s.parseState(c, state.Value)
	if err != nil {
		return
	}

	s.authLoginCallback(c, stateData, code)
}

// AuthLoginPostCallback is function to catch login callback from OAuth application

View on GitHub (pinned to ea665308ba)

Solutions

  1. Make sure the browser sends the state cookie (same-site settings, same domain, cookies not blocked)
  2. Start the login flow again via /auth/login so a fresh state parameter and cookie are issued
  3. Verify the IdP passes the state parameter through unchanged on redirect
  4. Check proxies/CDNs are not stripping query parameters from the callback URL

Example fix

// before
const cb = '/auth/login-callback'
// after
const params = new URLSearchParams(redirectParams)
const cb = `/auth/login-callback?code=${params.get('code')}&state=${params.get('state')}`
Defensive patterns

Strategy: validation

Validate before calling

const url = new URL(window.location.href)
if (!url.searchParams.get('state')) {
  // cookies likely blocked or flow broken; restart login
}

Prevention

When it happens

Trigger: GET /auth/login-callback without ?state=...; or the state value differs from the one stored in the state cookie (same error code, this specific message only when the query param is empty).

Common situations: Browser blocking/stripping cookies (third-party cookie restrictions) so the state cookie is missing; IdP configured to drop the state parameter; user opening the callback link in a different browser than the one that started login; SPA stripping query params before calling the backend.

Related errors


AI-assisted analysis of vxcontrol/pentagi@ea665308ba (2026-09-01). Data as JSON: /api/errors/28963b91fe41cc4f. Report an issue: GitHub.