{"record":{"id":"5cf23ec9d975fe39","repo":"hashicorp/terraform","slug":"sastoken-cannot-be-empty","errorCode":null,"errorMessage":"sasToken cannot be empty","messagePattern":"sasToken cannot be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/backend/remote-state/azure/api_client.go","lineNumber":57,"sourceCode":"\taccessKey          string\n\tsasToken           string\n\tazureAdStorageAuth auth.Authorizer\n}\n\nfunc buildClient(ctx context.Context, config BackendConfig) (*Client, error) {\n\tclient := Client{\n\t\tenvironment:        config.AuthConfig.Environment,\n\t\tstorageAccountName: config.StorageAccountName,\n\t}\n\n\tvar armAuthRequired bool\n\tswitch {\n\tcase config.AccessKey != \"\":\n\t\tclient.accessKey = config.AccessKey\n\tcase config.SasToken != \"\":\n\t\tsasToken := config.SasToken\n\t\tif strings.TrimSpace(sasToken) == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"sasToken cannot be empty\")\n\t\t}\n\t\tclient.sasToken = strings.TrimPrefix(sasToken, \"?\")\n\tcase config.UseAzureADAuthentication:\n\t\tvar err error\n\t\tclient.azureAdStorageAuth, err = auth.NewAuthorizerFromCredentials(ctx, *config.AuthConfig, config.AuthConfig.Environment.Storage)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to build authorizer for Storage API: %+v\", err)\n\t\t}\n\tdefault:\n\t\t// AAD authentication (ARM scope) is required only when no auth method is specified, which falls back to listing the access key via ARM API.\n\t\tarmAuthRequired = true\n\t}\n\n\t// If `config.LookupBlobEndpoint` is true, we need to authenticate with ARM to lookup the blob endpoint\n\tif config.LookupBlobEndpoint {\n\t\tarmAuthRequired = true\n\t}\n","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/backend/remote-state/azure/api_client.go#L39-L75","documentation":"Thrown by the Azure remote-state backend's buildClient when config.SasToken is non-empty (so the SAS branch was selected) but strings.TrimSpace(sasToken) is empty, meaning the supplied value was only whitespace. The non-empty check that selected the branch passes for whitespace-only strings, so this guard catches the degenerate case explicitly.","triggerScenarios":"sas_token in the azurerm backend block, or the matching env var (ARM_SAS_TOKEN), is set to a string of only spaces, tabs, or newlines. The switch case config.SasToken != \"\" is taken, then the trim check fails.","commonSituations":"A CI secret that resolved to whitespace (e.g. a quoted space in the CI variable definition), copy-paste of just the leading '?' of a SAS query string without the rest, or a templating system that left blanks. Also seen when the env var inherited a stray trailing newline combined with no real token.","solutions":["Provide a complete, non-whitespace SAS token (typically starts with 'sv=' or '?' followed by key=value pairs).","Trim and validate the secret at the CI/secret store before injecting it, so whitespace-only values fail earlier.","If you did not mean to use SAS, unset sas_token / ARM_SAS_TOKEN so a different auth branch (access key, AAD, ARM-fallback) is selected.","Prefer use_azuread_authentication=true with proper SP credentials for less error-prone auth."],"exampleFix":"# before: secret resolved to spaces\nexport ARM_SAS_TOKEN=\"   \"   # -> sasToken cannot be empty\n# after: real token (with or without leading '?')\nexport ARM_SAS_TOKEN=\"sv=2021-06-08&ss=bfqt&srt=sco&sp=rwdlacupiydd&se=...&sig=...\"","handlingStrategy":"validation","validationCode":"// Validate a SAS token env before terraform runs.\nfunc validSAS(v string) error {\n    if strings.TrimSpace(v) == \"\" { return fmt.Errorf(\"SAS token is empty/whitespace\") }\n    return nil\n}","typeGuard":"null","tryCatchPattern":"client, err := azure.NewClient(ctx, cfg)\nif err != nil && strings.Contains(err.Error(), \"sasToken cannot be empty\") {\n    // re-check the injected secret and surface a clearer message\n}","preventionTips":["Inject SAS tokens via a secret manager that rejects whitespace-only values.","Prefer use_azuread_authentication over SAS for less error-prone auth.","If you do not need SAS, unset ARM_SAS_TOKEN so a different auth branch is taken."],"tags":["azure","backend","authentication","sas-token","configuration"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}