siyuan-note/siyuan · error

Account authentication failed, please login again

Error message

Account authentication failed, please login again

What it means

Returned by UploadAssets2Cloud (assets.go:1342) when the SiYuan cloud upload endpoint /apis/siyuan/upload responds with HTTP 401. The text is the kernel i18n key 31 ("Account authentication failed, please login again"). The request carries a symphony cookie whose value is the upload token fetched from LoadUploadToken; the 401 means that token (or the underlying user account session) is no longer accepted by the cloud server.

Source

Thrown at kernel/model/assets.go:1342

			util.PushUpdateMsg(msgId, msg, 3000)
		}

		requestResult := gulu.Ret.NewResult()
		request := httpclient.NewCloudFileRequest2m()
		resp, reqErr := request.
			SetSuccessResult(requestResult).
			SetFile("file[]", absAsset).
			SetCookies(&http.Cookie{Name: "symphony", Value: uploadToken}).
			SetHeader("meta-type", metaType).
			SetHeader("biz-type", bizType).
			Post(util.GetCloudServer() + "/apis/siyuan/upload?ver=" + util.Ver)
		if nil != reqErr {
			logging.LogErrorf("upload assets failed: %s", reqErr)
			return count, ErrFailedToConnectCloudServer
		}

		if 401 == resp.StatusCode {
			err = errors.New(Conf.Language(31))
			return
		}

		if 0 != requestResult.Code {
			logging.LogErrorf("upload assets failed: %s", requestResult.Msg)
			err = fmt.Errorf(Conf.Language(94), requestResult.Msg)
			return
		}

		absAsset = filepath.ToSlash(absAsset)
		relAsset := absAsset[strings.Index(absAsset, "assets/"):]
		completedUploadAssets = append(completedUploadAssets, relAsset)
		logging.LogInfof("uploaded asset [%s]", relAsset)
		count++
	}

	if !ignorePushMsg {
		util.PushClearMsg(msgId)

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Re-login to the SiYuan cloud account (Settings - About - Account - login) so Conf.GetUser().UserToken is refreshed, then retry the upload; LoadUploadToken will fetch a fresh upload token.
  2. If re-login does not clear it, restart the kernel so the in-memory uploadToken/uploadTokenTime are reset and the next call forces LoadUploadToken to request a new token.
  3. Verify network reachability of util.GetCloudServer() and that no proxy strips the symphony cookie; a 401 here is auth, not connectivity (connectivity yields ErrFailedToConnectCloudServer).

Example fix

// before: upload attempted with a possibly stale cached token
count, err = uploadAssets2Cloud(assets, bizTypeUploadAssets, ignorePushMsg)

// after: force token refresh when a 401-shaped error is observed, then retry once
if errors.Is(err, ErrFailedToConnectCloudServer) || strings.Contains(fmt.Sprint(err), Conf.Language(31)) {
    uploadTokenTime = 0 // invalidate cache so LoadUploadToken re-fetches
    if loadErr := LoadUploadToken(); loadErr == nil {
        count, err = uploadAssets2Cloud(assets, bizTypeUploadAssets, ignorePushMsg)
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// Before triggering cloud upload, ensure the account session is alive.
if (!window.siyuan.user || !window.siyuan.user.userToken) {
  showMessage(window.siyuan.languages[31]) // prompt re-login
  return
}
await uploadAssets2Cloud(assets, "upload-assets")

Try / catch

// Distinguish auth (401) from transport and business errors.
try {
  await fetchPost('/api/asset/uploadCloud', { ... })
} catch (e) {
  const msg = String(e.message || e)
  if (msg.includes(window.siyuan.languages[31])) {
    // auth stale -> re-login flow, then retry once
    await openAccountLogin()
  } else if (msg.includes('failed to connect cloud server')) {
    // transport; do not retry blindly
  } else {
    // business error (421); surface server message
    showMessage(msg)
  }
}

Prevention

When it happens

Trigger: Calling asset cloud upload (action path uploadAssets2Cloud with bizType "upload-assets") or export-to-Liandi (bizType "export-liandi") after the user's account session expired, after logout/relogin on another device, or when LoadUploadToken silently obtained a token for an account whose UserToken is stale. The guard fires only when resp.StatusCode == 401, distinct from a network error (ErrFailedToConnectCloudServer) and from a non-zero business code (error 421).

Common situations: User logged out of the SiYuan account in another client but kept working locally; token cache (uploadToken/uploadTokenTime, refreshed at most hourly) holds a token bound to a dead session; clock skew on the server invalidating the session; subscription ended and the account was de-authenticated.

Understand the failure class

Related errors


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