siyuan-note/siyuan · error

OIDC validation transaction was not found or has expired

Error message

OIDC validation transaction was not found or has expired

What it means

activateOIDCValidation could not resolve the poll token to a validate-flow transaction that is completed, successful, and has a matching binding. Activation only runs against a transaction that finished the IdP round-trip successfully.

Source

Thrown at kernel/model/oidc.go:830

	state := oidcTransactions.byPoll[pollToken]
	transaction := oidcTransactions.byState[state]
	if transaction == nil || (transaction.Flow != oidcFlowDesktop && transaction.Flow != oidcFlowValidate) ||
		binding == "" || binding != transaction.Binding {
		return nil, false
	}
	copy := *transaction
	return &copy, true
}

func activateOIDCValidation(pollToken, binding string) (activated bool, err error) {
	oidcTransactions.Lock()
	defer oidcTransactions.Unlock()
	cleanupOIDCTransactionsLocked()
	state := oidcTransactions.byPoll[pollToken]
	transaction := oidcTransactions.byState[state]
	if transaction == nil || transaction.Flow != oidcFlowValidate || transaction.Binding == "" ||
		binding == "" || transaction.Binding != binding || !transaction.Completed || !transaction.Success {
		return false, errors.New("OIDC validation transaction was not found or has expired")
	}
	if transaction.Activated {
		return false, nil
	}
	if transaction.Config == nil {
		return false, errors.New("OIDC validation configuration is missing")
	}
	configurationChanged, swapped := Conf.CompareAndSetOIDC(transaction.ConfigVersion, transaction.Config)
	if !swapped {
		deleteOIDCTransactionLocked(state)
		return false, errors.New("OIDC configuration changed during validation")
	}
	transaction.Config = nil
	transaction.Activated = true
	return configurationChanged, nil
}

func cancelOIDCValidation(pollToken, binding string) bool {

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Re-run validation from /api/system/oidc/validate to get a fresh poll token.
  2. Activate within the completed window (30 seconds after the IdP success).
  3. Confirm the poll token and binding match the validation session that was started.
Defensive patterns

Strategy: validation

Validate before calling

// Only call validateActivate after a successful poll; require non-empty poll token and binding.
if pollToken == "" || binding == "" {
    return errors.New("poll token and binding are required")
}
if tx, ok := pollOIDCTransaction(pollToken, binding); !ok || !tx.Completed || !tx.Success {
    return errors.New("validation not ready; poll again")
}

Prevention

When it happens

Trigger: Calling /api/system/oidc/validateActivate with a stale or wrong poll token, before validation completed, after it failed, after its 30s completed window elapsed, after cancellation, or with the wrong binding.

Common situations: User clicks Activate twice or after a delay; poll token copy-paste error; activation attempted against a transaction whose binding changed.

Related errors


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