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
- Read the full error text after the localized prefix — it contains the underlying cause (auth, DNS, TLS, etc.) and fix that
- Verify cloud provider credentials and endpoint in Settings - Account & Sync (test connection)
- Check network connectivity and TLS/SkipTLS settings for self-signed endpoints
- For S3, confirm the bucket exists and the access key has List/Get permissions; for WebDAV, confirm the URL and account
- 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
- Parse the text after 'Failed to obtain cloud info' — it names the real underlying cause
- Test the cloud provider connection in Settings before relying on cloud statistics
- Keep provider credentials and endpoint settings current; rotate keys before expiry
- Handle transient network failures with retries rather than surfacing immediately
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
- Backup failed
- Conf.Language(30) + " " + err.Error()
- Backup failed: The cloud can only support backup up to 12…
- bazaar package information has not synced yet
- cloud server result message (result.Msg)
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)