juicedata/juicefs · error
Failed to create Azure blob client with SAS token: %v
Error message
Failed to create Azure blob client with SAS token: %v
What it means
Thrown when azblob.NewClientWithNoCredential cannot construct an azblob.Client from the SAS URL (<scheme>://<account>.<domain>?<sas>). This happens after endpoint discovery succeeded, and indicates the assembled SAS URL is malformed.
Source
Thrown at pkg/object/azure.go:345
// Priority 2: No account key — use SAS token or managed identity
if accountKey == "" {
domain := domainFromHost(hostParts)
normalized := normalizeSASToken(token)
if normalized != "" {
if domain == "" {
var err error
if domain, err = autoWasbEndpoint(accountName, uri.Scheme, func(serviceURL string) (*azblob.Client, error) {
return azblob.NewClientWithNoCredential(serviceURL+"?"+normalized, nil)
}); err != nil {
return nil, fmt.Errorf("Unable to get endpoint of container %s: %s", containerName, err)
}
}
sasURL := fmt.Sprintf("%s://%s.%s?%s", uri.Scheme, accountName, domain, normalized)
client, err := azblob.NewClientWithNoCredential(sasURL, azblobOptions())
if err != nil {
return nil, fmt.Errorf("Failed to create Azure blob client with SAS token: %v", err)
}
return &wasb{container: client.ServiceClient().NewContainerClient(containerName), azblobCli: client, cName: containerName, useTokenAuth: true}, nil
}
tokenCred, err := createAzureCredential()
if err != nil {
return nil, fmt.Errorf("Failed to create Azure credential (managed identity/Azure CLI): %v", err)
}
if domain == "" {
if domain, err = autoWasbEndpoint(accountName, uri.Scheme, func(serviceURL string) (*azblob.Client, error) {
return azblob.NewClient(serviceURL, tokenCred, nil)
}); err != nil {
return nil, fmt.Errorf("Unable to get endpoint of container %s: %s", containerName, err)
}
}
serviceURL := fmt.Sprintf("%s://%s.%s", uri.Scheme, accountName, domain)
client, err := azblob.NewClient(serviceURL, tokenCred, azblobOptions())
if err != nil {View on GitHub (pinned to c9a67b23e8)
Solutions
- Inspect the SAS token for whitespace, quotes, or a leading '?'; trim/normalize it.
- Provide the endpoint with an explicit full domain so a bad auto-discovered domain is not used.
- Validate the final URL parses with url.Parse before constructing the client.
- Regenerate the SAS token from the Azure portal/CLI.
Example fix
// before endpoint: "azblob://acct.blob.core.windows.net? token=sv=..." (space inside token) // after endpoint: "azblob://acct.blob.core.windows.net?sv=2020-02-10&ss=b&srt=sco"
Defensive patterns
Strategy: validation
Validate before calling
sas := strings.TrimSpace(sasToken)
sas = strings.TrimPrefix(sas, "?")
if sas == "" { return errors.New("empty SAS token") }
if _, err := url.Parse("https://acct.blob.core.windows.net?" + sas); err != nil { return err } Try / catch
client, err := azblob.NewClientWithNoCredential(sasURL, nil)
if err != nil {
return fmt.Errorf("bad SAS URL %q: %w", redact(sasURL), err)
} Prevention
- Trim whitespace and newlines from SAS tokens when loading config
- Never include a leading '?' in the SAS token field
- Store the token URL-encoded and validated at startup
When it happens
Trigger: newWasb with SAS auth where the discovered domain combined with the account name and SAS query produces a URL the SDK rejects (empty/invalid domain discovered, invalid characters in SAS token).
Common situations: SAS token copied with stray whitespace/newlines; SAS token missing leading '?'; auto-discovered domain empty or garbage; non-URL-safe characters pasted from config files.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- Failed to create Azure blob client with token credential: %v
- Unable to get endpoint of container %s: %s
- Invalid endpoint: %v, error: %v
- ceph: can't put empty file
- GOOGLE_CLOUD_PROJECT environment variable must be set
AI-assisted analysis of juicedata/juicefs@c9a67b23e8 (2026-09-06).
Data as JSON: /api/errors/4f3adcd6dab91b42.
Report an issue: GitHub.