siyuan-note/siyuan · error
OIDC login binding does not match
Error message
OIDC login binding does not match
What it means
Transactions are bound to a per-client binding value (desktop window binding / mobile flow). claimOIDCTransaction requires the binding supplied at claim time to equal the one stored at creation, unless the desktop/validate flow explicitly allows claiming without a binding. On mismatch (or a missing binding when required) it fails with this error, preventing one browser context from hijacking another's login.
Solutions
- Complete the login in the same browser/window that initiated it
- Start a new OIDC login from the client that should receive the session
- Check that cookies/local storage holding the binding are not being cleared or blocked (third-party cookie settings, private mode)
Defensive patterns
Strategy: validation
Validate before calling
// client side: refuse to open the callback without the stored binding
if binding == "" {
return errors.New("missing OIDC binding; restart login from the original window")
} Prevention
- Finish the login in the same browser/window that started it
- Do not clear cookies or use private mode mid-login
- Keep the desktop window alive until the login completes
When it happens
Trigger: OIDCCallback/OIDCMobileCallback presents a binding that differs from the transaction's Binding, or an empty binding for a flow that requires one (non-desktop/validate flows).
Common situations: Completing the login in a different browser or device than the one that started it; cookie/session lost so the binding is empty; a desktop window restarted between start and callback; proxy altering cookies.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- A loopback OIDC redirect URL is required for local access
- A public HTTPS OIDC redirect URL is required for remote…
- attribute view [ ] is not bound
- Conf.Language(381)
- decode OIDC claims failed
AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19).
Data as JSON: /api/errors/9d5e8d1d60a42c4d.
Report an issue: GitHub.
Appendix: source
Thrown at kernel/model/oidc.go:699
if state == "" {
return nil, false, errors.New("OIDC state is missing")
}
oidcTransactions.Lock()
cleanupOIDCTransactionsLocked()
transaction := oidcTransactions.byState[state]
if transaction == nil {
oidcTransactions.Unlock()
return nil, false, errors.New("OIDC login transaction was not found or has expired")
}
if transaction.ConfigVersion != oidcConfigurationVersion(Conf.GetOIDC()) {
deleteOIDCTransactionLocked(state)
oidcTransactions.Unlock()
return nil, false, errors.New("OIDC configuration changed during login")
}
if !(allowDesktopWithoutBinding && (transaction.Flow == oidcFlowDesktop || transaction.Flow == oidcFlowValidate)) &&
(binding == "" || binding != transaction.Binding) {
oidcTransactions.Unlock()
return nil, false, errors.New("OIDC login binding does not match")
}
if !transaction.Claimed {
transaction.Claimed = true
copy := *transaction
oidcTransactions.Unlock()
return ©, false, nil
}
done := transaction.Done
oidcTransactions.Unlock()
select {
case <-ctx.Done():
return nil, false, fmt.Errorf("wait for OIDC login transaction failed: %w", ctx.Err())
case <-done:
}
oidcTransactions.Lock()
defer oidcTransactions.Unlock()View on GitHub (pinned to 9f775e8a12)