siyuan-note/siyuan · error

Failed to obtain cloud info

Error message

Failed to obtain cloud info

What it means

GetCloudSpace queries the user's cloud storage statistics (sync space, assets, backup sizes, traffic). If the underlying getCloudSpace call fails (network error, auth failure, provider error), the kernel wraps the cause as Conf.Language(30) + " " + err.Error() — localized as "Failed to obtain cloud info". The original provider error text is appended after the localized prefix.

Solutions

  1. Read the full error text after the localized prefix — it contains the underlying cause (auth, DNS, TLS, etc.) and fix that
  2. Verify cloud provider credentials and endpoint in Settings - Account & Sync (test connection)
  3. Check network connectivity and TLS/SkipTLS settings for self-signed endpoints
  4. For S3, confirm the bucket exists and the access key has List/Get permissions; for WebDAV, confirm the URL and account
  5. Retry after transient network issues — getCloudSpace failures are often connectivity-related

Example fix

// handling the wrapped error in a client
const res = await fetch('/api/sync/getCloudSpace', {method:'POST'});
const j = await res.json();
if (j.code !== 0) {
  // j.msg = "Failed to obtain cloud info <root cause>"
  if (/401|Unauthorized|AccessDenied/.test(j.msg)) reconfigureCredentials();
  else if (/no such host|timeout|connection/.test(j.msg)) checkNetwork();
}
Defensive patterns

Strategy: try-catch

Validate before calling

// probe connectivity/auth before requesting cloud space
const res = await fetch('/api/sync/getCloudSpace', {method:'POST'});
const j = await res.json();
if (j.code !== 0) console.warn('Cloud info unavailable:', j.msg); // msg includes root cause after the localized prefix

Type guard

function isCloudInfoError(msg) { return typeof msg === 'string' && msg.startsWith('Failed to obtain cloud info'); }

Try / catch

try {
  const stat = await getCloudSpace();
} catch (e) {
  if (/Unauthorized|AccessDenied|401|403/.test(e.message)) reconfigureProviderCredentials();
  else if (/timeout|no such host|connection refused/.test(e.message)) await retryWithBackoff(getCloudSpace, 3);
  else throw e;
}

Prevention

When it happens

Trigger: Opening the cloud storage/sync statistics UI or calling the cloudSpace API while the kernel cannot reach or authenticate to the configured cloud provider (S3/WebDAV/Local endpoint).

Common situations: S3/WebDAV credentials wrong or expired; endpoint unreachable (offline, DNS, firewall, TLS issues); bucket/container missing or permission denied; provider returning an unexpected response; using Local provider with a bad endpoint path.

Related errors


AI-assisted analysis of siyuan-note/siyuan@9f775e8a12 (2026-09-19). Data as JSON: /api/errors/82e6b673e0fefb04. Report an issue: GitHub.

Appendix: source

Thrown at kernel/model/repository.go:3350

type Backup struct {
	Size    int64  `json:"size"`
	HSize   string `json:"hSize"`
	Updated string `json:"updated"`
	SaveDir string `json:"saveDir"` // 本地备份数据存放目录路径
}

type Sync struct {
	Size      int64  `json:"size"`
	HSize     string `json:"hSize"`
	Updated   string `json:"updated"`
	CloudName string `json:"cloudName"` // 云端同步数据存放目录名
	SaveDir   string `json:"saveDir"`   // 本地同步数据存放目录路径
}

func GetCloudSpace() (s *Sync, b *Backup, hSize, hAssetSize, hTotalSize, hExchangeSize, hTrafficUploadSize, hTrafficDownloadSize, hTrafficAPIGet, hTrafficAPIPut string, err error) {
	stat, err := getCloudSpace()
	if err != nil {
		err = errors.New(Conf.Language(30) + " " + err.Error())
		return
	}

	syncSize := stat.Sync.Size
	syncUpdated := stat.Sync.Updated
	s = &Sync{
		Size:    syncSize,
		HSize:   "-",
		Updated: syncUpdated,
	}

	backupSize := stat.Backup.Size
	backupUpdated := stat.Backup.Updated
	b = &Backup{
		Size:    backupSize,
		HSize:   "-",
		Updated: backupUpdated,
	}

View on GitHub (pinned to 9f775e8a12)