apache/hadoop · error · SASTokenProviderException
"%s" must be set for user-bound SAS auth type.
Error message
"%s" must be set for user-bound SAS auth type.
What it means
Thrown by AbfsConfiguration.getUserBoundSASTokenProvider during FileSystem initialization when the auth type is a user-bound SAS mode (UserboundSAS or UserboundSASWithOAuth) but fs.azure.sas.token.provider.type is not configured. User-bound SAS has no built-in token source, so hadoop-azure requires a user-supplied class implementing SASTokenProvider to obtain per-user SAS tokens. Without that key there is no credential source and initialization aborts with SASTokenProviderException.
Source
Thrown at hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/AbfsConfiguration.java:1686
/**
* Returns the SASTokenProvider implementation to be used to generate user-bound SAS token.
* Custom implementation of {@link SASTokenProvider} under th config
* "fs.azure.sas.token.provider.type" needs to be provided.
* @param authType authentication type
* @return sasTokenProvider object based on configurations provided
* @throws AzureBlobFileSystemException is user-bound SAS token provider initialization fails
*/
public SASTokenProvider getUserBoundSASTokenProvider(AuthType authType)
throws AzureBlobFileSystemException {
try {
Class<? extends SASTokenProvider> customSasTokenProviderImplementation =
getTokenProviderClass(authType, FS_AZURE_SAS_TOKEN_PROVIDER_TYPE,
null, SASTokenProvider.class);
if (customSasTokenProviderImplementation == null) {
throw new SASTokenProviderException(String.format(
"\"%s\" must be set for user-bound SAS auth type.",
FS_AZURE_SAS_TOKEN_PROVIDER_TYPE));
}
SASTokenProvider sasTokenProvider = ReflectionUtils.newInstance(
customSasTokenProviderImplementation, rawConfig);
if (sasTokenProvider == null) {
throw new SASTokenProviderException(String.format(
"Failed to initialize %s", customSasTokenProviderImplementation));
}
LOG.trace("Initializing {}", customSasTokenProviderImplementation.getName());
sasTokenProvider.initialize(rawConfig, accountName);
LOG.trace("{} init complete", customSasTokenProviderImplementation.getName());
return sasTokenProvider;
} catch (SASTokenProviderException e) {
throw e;
} catch (Exception e) {
throw new SASTokenProviderException(View on GitHub (pinned to 2add963021)
Solutions
- Set fs.azure.sas.token.provider.type to the fully-qualified name of a class implementing org.apache.hadoop.fs.azurebfs.extensions.SASTokenProvider (e.g. com.example.UserSASTokenProvider).
- If you do not need per-user tokens, use the fixed-token mode instead: set fs.azure.sas.fixed.token (account-specific form fs.azure.account.<account>.sas.fixed.token) and leave the custom provider unset.
- Verify the key is visible to the code creating the FileSystem: print conf.get("fs.azure.sas.token.provider.type") from the same Configuration object.
- Ensure the provider class is on the runtime classpath with a public no-arg constructor.
Example fix
// before <property><name>fs.azure.account.auth.type</name><value>UserboundSASWithOAuth</value></property> <!-- fs.azure.sas.token.provider.type missing --> // after <property><name>fs.azure.account.auth.type</name><value>UserboundSASWithOAuth</value></property> <property><name>fs.azure.sas.token.provider.type</name><value>com.example.UserSASTokenProvider</value></property>
Defensive patterns
Strategy: validation
Validate before calling
String authType = conf.get("fs.azure.account.auth.type", "SharedKey");
if ("SAS".equals(authType) || "UserboundSASWithOAuth".equals(authType)) {
if (conf.get("fs.azure.sas.token.provider.type") == null
&& conf.get("fs.azure.account." + accountName + ".sas.token.provider.type") == null) {
throw new IOException("fs.azure.sas.token.provider.type must be set for user-bound SAS auth");
}
}
FileSystem fs = path.getFileSystem(conf); Try / catch
try {
FileSystem fs = path.getFileSystem(conf);
} catch (SASTokenProviderException | InvalidConfigurationValueException e) {
throw new IOException("ABFS init failed (check SAS token provider config): " + e.getMessage(), e);
} Prevention
- Deploy the provider class and fs.azure.sas.token.provider.type together when enabling user-bound SAS.
- Prefer account-specific key forms in multi-account setups.
- Add a deploy-time smoke test that constructs the FileSystem.
When it happens
Trigger: fs.azure.account.auth.type is SAS (user-bound) or UserboundSASWithOAuth while fs.azure.sas.token.provider.type is absent from the job Configuration (only the global or only the wrong account-specific spelling is set), so getTokenProviderClass(authType, FS_AZURE_SAS_TOKEN_PROVIDER_TYPE, null, SASTokenProvider.class) returns null. Reached via AzureBlobFileSystemStore provider setup and getUserBoundSASBothTokenProviders().
Common situations: Migrating an abfs:// cluster from SharedKey or fixed-SAS to user-bound SAS and forgetting the provider class; typo in the key name; key set in core-site.xml but the job uses an account-specific Configuration; upgrading to a Hadoop version where user-bound SAS validation was added.
Related errors
- Invalid URI %s - account name is not fully qualified.
- Unable to load user-bound SAS token provider class: {e}
- ABFS endpoint is not set correctly : %s, Do not specify sche
- Invalid URI %s
- Both global key and encryption context are set, only one all
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/f024da2504a614ff.
Report an issue: GitHub.