apache/hadoop · error · SASTokenProviderException

Failed to acquire a SAS token for %s on %s due to %s

Error message

Failed to acquire a SAS token for %s on %s due to %s

What it means

The catch-all for SAS token acquisition: any exception thrown while fetching or applying the SAS token for a given operation/path is wrapped in SASTokenProviderException with this formatted message. The fault is in the SASTokenProvider implementation or its backing secret store, not in Azure Storage itself — inspect the chained cause for the real error.

Source

Thrown at hadoop-tools/hadoop-azure/src/main/java/org/apache/hadoop/fs/azurebfs/services/AbfsClient.java:1181

          sasToken = sasTokenProvider.getSASToken(this.accountName,
              this.filesystem, path, operation);
          if ((sasToken == null) || sasToken.isEmpty()) {
            throw new UnsupportedOperationException("SASToken received is empty or null");
          }
        } else {
          sasToken = cachedSasToken;
          LOG.trace("Using cached SAS token.");
        }

        // if SAS Token contains a prefix of ?, it should be removed
        if (sasToken.charAt(0) == '?') {
          sasToken = sasToken.substring(1);
        }

        queryBuilder.setSASToken(sasToken);
        LOG.trace("SAS token fetch complete for {} on {}", operation, path);
      } catch (Exception ex) {
        throw new SASTokenProviderException(String.format(
            "Failed to acquire a SAS token for %s on %s due to %s", operation, path,
            ex.toString()), ex);
      }
    }
    return sasToken;
  }

  /**
   * Creates REST operation URL with empty path for the given query.
   * @param query to be added to the URL.
   * @return URL for the REST operation.
   * @throws AzureBlobFileSystemException if URL creation fails.
   */
  @VisibleForTesting
  protected URL createRequestUrl(final String query) throws AzureBlobFileSystemException {
    return createRequestUrl(EMPTY_STRING, query);
  }

View on GitHub (pinned to 2add963021)

Solutions

  1. Read the cause (getCause()/toString() in the message) — it names the actual failure inside the provider.
  2. Verify the provider class configured for fs.azure.account.sastokenprovider exists, is instantiable, and its dependencies are on the classpath of every node.
  3. Check credentials and network access from all nodes to the secret store backing the provider.
  4. Add retry/caching inside the provider for transient secret-store failures so single blips don't fail Hadoop jobs.

Example fix

// before: provider bubbles raw KeyVault SDK errors to AbfsClient
// after: provider handles transient failures itself
public String getSASToken(String account, String fs, String path, String op)
    throws SASTokenProviderException {
  return retryOnTransient(3,
      () -> keyVault.getSecret(sasSecretName(account, op)),
      ex -> ex instanceof SecretNotFoundException == false);
}
Defensive patterns

Strategy: try-catch

Try / catch

catch (SASTokenProviderException ex) {
  Throwable cause = ex.getCause();
  if (isTransientSecretStoreError(cause)) { retryWithBackoff(op); }
  else { alert("SAS provider failure: " + cause); throw ex; }
}

Prevention

When it happens

Trigger: The provider throws during getSASToken (KeyVault unreachable, missing secret, auth failure, timeout), or the inner empty-token UnsupportedOperationException is re-wrapped here; also a malformed token whose '?' stripping or query application fails.

Common situations: Custom providers hitting KeyVault outages or RBAC permission loss; expired service principals used to fetch tokens; network rules blocking the secret store from executor nodes; typos in fs.azure.account.sastokenprovider class name causing instantiation errors surfaced on first use.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/3ec2e691f117b489. Report an issue: GitHub.