siyuan-note/siyuan · error
invalid publish service token
Error message
invalid publish service token
What it means
ErrInvalidPublishServiceToken is the sentinel error returned when a JWT presented as a publish-service token fails validation (IsValidPublishServiceToken returns false during ParseJWT). Publish-service tokens are issued for the publish feature's accounts; once a publish account is (re)initialized the old signing context no longer validates, so tokens signed under the stale account are rejected.
Source
Thrown at kernel/model/auth.go:80
// publishSessionTTL 发布服务会话空闲过期时长,超过后需要重新认证
publishSessionTTL = 7 * 24 * time.Hour
// publishSessionGlobalCap 发布服务会话全局上限,超出后淘汰最久未活跃的会话
publishSessionGlobalCap = 4096
// publishSessionPerAccountCap 单账户会话上限,超出后淘汰该账户最久未活跃的会话
publishSessionPerAccountCap = 32
)
var (
accountsMap = AccountsMap{}
accountsLock = sync.RWMutex{}
sessionsMap = map[string]*PublishSession{}
sessionLock = sync.Mutex{}
jwtKey = make([]byte, 32)
jwtKeyOnce sync.Once
ErrInvalidPublishServiceToken = errors.New("invalid publish service token")
)
func InitJwtKey() {
jwtKeyOnce.Do(func() {
err := refreshJwtKey()
if err != nil {
logging.LogFatalf(logging.ExitCodeFatal, "initialize JWT signing key failed: %s", err)
}
})
}
func refreshJwtKey() error {
if _, err := rand.Read(jwtKey); err != nil {
logging.LogErrorf("generate JWT signing key failed: %s", err)
return err
}
return nil
}View on GitHub (pinned to 8641553a1f)
Solutions
- Re-authenticate against the publish service to obtain a fresh token and retry the request
- Check whether the publish account was re-initialized; update clients with the new account/token
- Verify the token's claims and expiry are intact and match the current publish account configuration
Example fix
// before
token := cachedPublishToken // issued before account re-init
claims, err := ParseJWT(token)
// after
token := cachedPublishToken
if _, err := ParseJWT(token); errors.Is(err, ErrInvalidPublishServiceToken) {
token = reloginPublishService() // fetch a fresh token
}
claims, err := ParseJWT(token) Defensive patterns
Strategy: try-catch
Validate before calling
let valid = true;
try { ParseJWT(token); } catch (e) { valid = !errors.Is(e, ErrInvalidPublishServiceToken); } Try / catch
claims, err := ParseJWT(token)
if errors.Is(err, ErrInvalidPublishServiceToken) {
token = refreshPublishServiceToken() // re-login and retry once
claims, err = ParseJWT(token)
} Prevention
- Refresh publish tokens after any publish account re-initialization or password change
- Use errors.Is(err, ErrInvalidPublishServiceToken) to detect stale tokens specifically
- Store tokens with their issuing account ID so stale pairs are detected early
When it happens
Trigger: Calling ParseJWT on a token where IsPublishServiceToken(token) is true but IsValidPublishServiceToken fails — e.g. the token was issued for a publish account that was later re-initialized, the token's account credentials no longer match, or the token is malformed/expired relative to the publish account state.
Common situations: A publish account was re-created or its password reset, invalidating previously issued JWTs still held by clients; stale tokens cached in a client after the publish service was reconfigured; clock skew or expiry making the publish token invalid.
Related errors
- Account authentication failed, please login again
- OIDC login is not enabled
- verify OIDC ID token failed: %w
AI-assisted analysis of siyuan-note/siyuan@8641553a1f (2026-09-11).
Data as JSON: /api/errors/b1555bda9ba9eae3.
Report an issue: GitHub.