siyuan-note/siyuan · warning

too many pending OIDC login transactions

Error message

too many pending OIDC login transactions

What it means

storeOIDCTransaction enforces per-source limits: oidcTransactionPerIP (32) pending transactions per client IP and oidcTransactionPerBind (8) per binding. Exceeding either rejects the new transaction to keep one source from saturating the store.

Source

Thrown at kernel/model/oidc.go:726

		transaction.Done = make(chan struct{})
	}
	if len(oidcTransactions.byState) >= oidcTransactionMax {
		return errors.New("OIDC login transaction capacity reached")
	}
	perIP, perBinding := 0, 0
	for _, candidate := range oidcTransactions.byState {
		if candidate.Completed {
			continue
		}
		if transaction.ClientIP != "" && candidate.ClientIP == transaction.ClientIP {
			perIP++
		}
		if transaction.Binding != "" && candidate.Binding == transaction.Binding {
			perBinding++
		}
	}
	if perIP >= oidcTransactionPerIP || perBinding >= oidcTransactionPerBind {
		return errors.New("too many pending OIDC login transactions")
	}
	oidcTransactions.byState[transaction.State] = transaction
	if transaction.PollToken != "" {
		oidcTransactions.byPoll[transaction.PollToken] = transaction.State
	}
	return nil
}

func claimOIDCTransaction(ctx context.Context, state, binding string,
	allowDesktopWithoutBinding bool) (*oidcTransaction, bool, error) {
	if state == "" {
		return nil, false, errors.New("OIDC state is missing")
	}
	oidcTransactions.Lock()
	cleanupOIDCTransactionsLocked()
	transaction := oidcTransactions.byState[state]
	if transaction == nil {
		oidcTransactions.Unlock()

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Close other pending login attempts for this user/session and retry.
  2. Wait for the older pending transactions to expire (up to 10 minutes).
  3. Confirm the client is not auto-retrying /api/system/oidc/start on transient failures.
Defensive patterns

Strategy: retry

Try / catch

// Per-source limit hit - back off; do not hammer start.
if err := storeOIDCTransaction(tx); err != nil && strings.Contains(err.Error(), "too many pending") {
    respondTooManyPending(c) // ask client to close other login tabs and retry
}

Prevention

When it happens

Trigger: A single client IP holds >= 32 pending transactions, or a single binding holds >= 8, when a new start arrives.

Common situations: User opens many login tabs; a misbehaving client auto-retries start in a loop on failure; shared office NAT concentrating many users behind one IP.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/18ca14bbfe9cf404. Report an issue: GitHub.