apache/hadoop · error · RuntimeException

Signer class [%s] not found for signer [%s]

Error message

Signer class [%s] not found for signer [%s]

What it means

SignerManager.maybeRegisterSigner loads the signer class of a custom signer entry (second segment) via conf.getClassByName. If it is not found, a RuntimeException wrapping the ClassNotFoundException is thrown, naming the missing signer class and its configured signer name. This happens once per name, at the first S3A filesystem initialization that references the custom signer.

Source

Thrown at hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/auth/SignerManager.java:129

  /**
   * Make sure the signer class is registered once with the AWS SDK.
   * @param signerName signer name
   * @param signerClassName classname
   * @param conf source configuration
   * @throws RuntimeException if the class is not found
   */
  private static void maybeRegisterSigner(String signerName,
      String signerClassName, Configuration conf) {

    if (!SignerFactory.isSignerRegistered(signerName)) {
      // Signer is not registered with the AWS SDK.
      // Load the class and register the signer.
      Class<? extends Signer> clazz;
      try {
        clazz = (Class<? extends Signer>) conf.getClassByName(signerClassName);
      } catch (ClassNotFoundException cnfe) {
        throw new RuntimeException(String
            .format("Signer class [%s] not found for signer [%s]",
                signerClassName, signerName), cnfe);
      }
      LOG.debug("Registering Custom Signer - [{}->{}]", signerName,
          clazz.getName());
      synchronized (SignerManager.class) {
        SignerFactory.registerSigner(signerName, clazz);
      }
    }
  }

  @Override public void close() throws IOException {
    LOG.debug("Unregistering fs from {} initializers", initializers.size());
    for (AwsSignerInitializer initializer : initializers) {
      initializer
          .unregisterStore(bucketName, ownerConf, delegationTokenProvider,
              ownerUgi);
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Fix the signer class FQCN in the fs.s3a.custom.signers entry
  2. Distribute the jar containing the signer to all nodes/clients that mount s3a (cluster share dir, Spark jars, MR libjars)
  3. Confirm the class actually extends the AWS SDK Signer type the cast expects, otherwise fix the type first

Example fix

<!-- before -->
<property><name>fs.s3a.custom.signers</name>
  <value>MySigner:com.example.mySigner</value></property>

<!-- after -->
<property><name>fs.s3a.custom.signers</name>
  <value>MySigner:com.example.MySigner</value></property>
Defensive patterns

Strategy: validation

Validate before calling

for (String entry : conf.getTrimmedStrings("fs.s3a.custom.signers")) {
  String[] p = entry.split(":");
  if (p.length >= 2) {
    Class<?> c = conf.getClassByName(p[1]); // clear CNFE here, before FS init
    if (!Signer.class.isAssignableFrom(c)) {
      throw new IllegalArgumentException(p[1] + " is not a Signer implementation");
    }
  }
}

Try / catch

try {
  fs.initialize(uri, conf);
} catch (RuntimeException e) {
  if (e.getCause() instanceof ClassNotFoundException
      && e.getMessage().contains("Signer class")) {
    throw new ConfigException("Missing signer class: " + e.getCause().getMessage(), e);
  }
  throw e;
}

Prevention

When it happens

Trigger: fs.s3a.custom.signers=Name:com.example.MissingSigner where that FQCN is misspelled, relocated by shading, or its jar is missing from the client classpath. Only thrown when the name is not already registered with the AWS SDK SignerFactory.

Common situations: Deploying config ahead of the jar (config references a class in a jar not yet rolled out); different classpaths on edge node vs cluster executors; jar present at submit time but not in the YARN container classpath.

Related errors


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