{"record":{"id":"f024da2504a614ff","repo":"apache/hadoop","slug":"s-must-be-set-for-user-bound-sas-auth-type","errorCode":null,"errorMessage":"\"%s\" must be set for user-bound SAS auth type.","messagePattern":"\"(.+?)\" must be set for user-bound SAS auth type\\.","errorType":"exception","errorClass":"SASTokenProviderException","httpStatus":null,"severity":"error","filePath":"hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/AbfsConfiguration.java","lineNumber":1686,"sourceCode":"\n  /**\n   * Returns the SASTokenProvider implementation to be used to generate user-bound SAS token.\n   * Custom implementation of {@link SASTokenProvider} under th config\n   * \"fs.azure.sas.token.provider.type\" needs to be provided.\n   * @param authType authentication type\n   * @return sasTokenProvider object based on configurations provided\n   * @throws AzureBlobFileSystemException is user-bound SAS token provider initialization fails\n   */\n  public SASTokenProvider getUserBoundSASTokenProvider(AuthType authType)\n      throws AzureBlobFileSystemException {\n\n    try {\n      Class<? extends SASTokenProvider> customSasTokenProviderImplementation =\n          getTokenProviderClass(authType, FS_AZURE_SAS_TOKEN_PROVIDER_TYPE,\n              null, SASTokenProvider.class);\n\n      if (customSasTokenProviderImplementation == null) {\n        throw new SASTokenProviderException(String.format(\n            \"\\\"%s\\\" must be set for user-bound SAS auth type.\",\n            FS_AZURE_SAS_TOKEN_PROVIDER_TYPE));\n      }\n\n        SASTokenProvider sasTokenProvider = ReflectionUtils.newInstance(\n            customSasTokenProviderImplementation, rawConfig);\n        if (sasTokenProvider == null) {\n          throw new SASTokenProviderException(String.format(\n              \"Failed to initialize %s\", customSasTokenProviderImplementation));\n        }\n        LOG.trace(\"Initializing {}\", customSasTokenProviderImplementation.getName());\n        sasTokenProvider.initialize(rawConfig, accountName);\n        LOG.trace(\"{} init complete\", customSasTokenProviderImplementation.getName());\n        return sasTokenProvider;\n    } catch (SASTokenProviderException e) {\n      throw e;\n    } catch (Exception e) {\n      throw new SASTokenProviderException(","sourceCodeStart":1668,"sourceCodeEnd":1704,"githubUrl":"https://github.com/apache/hadoop/blob/2add9630210752f88ceb1bb74eb65e37bf41da8e/hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/AbfsConfiguration.java#L1668-L1704","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","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."],"exampleFix":"// before\n<property><name>fs.azure.account.auth.type</name><value>UserboundSASWithOAuth</value></property>\n<!-- fs.azure.sas.token.provider.type missing -->\n\n// after\n<property><name>fs.azure.account.auth.type</name><value>UserboundSASWithOAuth</value></property>\n<property><name>fs.azure.sas.token.provider.type</name><value>com.example.UserSASTokenProvider</value></property>","handlingStrategy":"validation","validationCode":"String authType = conf.get(\"fs.azure.account.auth.type\", \"SharedKey\");\nif (\"SAS\".equals(authType) || \"UserboundSASWithOAuth\".equals(authType)) {\n  if (conf.get(\"fs.azure.sas.token.provider.type\") == null\n      && conf.get(\"fs.azure.account.\" + accountName + \".sas.token.provider.type\") == null) {\n    throw new IOException(\"fs.azure.sas.token.provider.type must be set for user-bound SAS auth\");\n  }\n}\nFileSystem fs = path.getFileSystem(conf);","typeGuard":null,"tryCatchPattern":"try {\n  FileSystem fs = path.getFileSystem(conf);\n} catch (SASTokenProviderException | InvalidConfigurationValueException e) {\n  throw new IOException(\"ABFS init failed (check SAS token provider config): \" + e.getMessage(), e);\n}","preventionTips":["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."],"tags":["azure","abfs","sas-token","configuration","authentication"],"backgroundTag":"missing-required-config","analyzedSha":"2add9630210752f88ceb1bb74eb65e37bf41da8e","analyzedAt":"2026-08-22T19:55:07.957Z","schemaVersion":2},"datasetVersion":"2026-08-22T20:17:22.307Z"}