shwenzhang/AndResGuard · error · ParameterException

Keystore Provider class

Error message

Keystore Provider class <keystoreProviderClass> not subclass of java.security.Provider

What it means

When --ks-provider-class is given, ApkSignerTool loads the class reflectively and verifies it extends java.security.Provider. If the named class is not a Provider subclass it throws this ParameterException, since only a Provider can back KeyStore.getInstance(ksType, provider).

Solutions

  1. Pass the actual JCE Provider class, e.g. --ks-provider-class org.bouncycastle.jce.provider.BouncyCastleProvider.
  2. Check the provider jar's documentation for the class that extends java.security.Provider.
  3. If the provider is already installed in the JVM, drop --ks-provider-class and use --ks-provider-name instead.
  4. Ensure the provider jar is on the classpath and Class.forName resolves the intended class.

Example fix

// before
--ks-provider-class org.bouncycastle.jce.BouncyCastle
// after
--ks-provider-class org.bouncycastle.jce.provider.BouncyCastleProvider
Defensive patterns

Strategy: validation

Validate before calling

// Java pre-check
Class<?> c = Class.forName(providerClassName);
if (!java.security.Provider.class.isAssignableFrom(c)) {
    throw new IllegalArgumentException(providerClassName + " is not a java.security.Provider");
}

Type guard

boolean isJceProvider(String name) {
  try { return java.security.Provider.class.isAssignableFrom(Class.forName(name)); }
  catch (ClassNotFoundException e) { return false; }
}

Prevention

When it happens

Trigger: Passing --ks-provider-class pointing to a class that exists but does not extend java.security.Provider (e.g. a JCE provider's factory/helper class, or a typo to a random class in the classpath).

Common situations: Using Bouncy Castle or a hardware-security provider and naming the wrong entry class; class loaded from an unrelated jar with the same package name; provider shipped in an old jar whose classes were repackaged.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of shwenzhang/AndResGuard@e4df245d82 (2026-09-12). Data as JSON: /api/errors/3631c0ec34b82205. Report an issue: GitHub.

Appendix: source

Thrown at AndResGuard-core/src/main/java/apksigner/ApkSignerTool.java:661

      }
    }

    private void loadPrivateKeyAndCertsFromKeyStore(PasswordRetriever passwordRetriever) throws Exception {
      if (keystoreFile == null) {
        throw new ParameterException("KeyStore (--ks) must be specified");
      }

      // 1. Obtain a KeyStore implementation
      String ksType = (keystoreType != null) ? keystoreType : KeyStore.getDefaultType();
      KeyStore ks;
      if (keystoreProviderName != null) {
        // Use a named Provider (assumes the provider is already installed)
        ks = KeyStore.getInstance(ksType, keystoreProviderName);
      } else if (keystoreProviderClass != null) {
        // Use a new Provider instance (does not require the provider to be installed)
        Class<?> ksProviderClass = Class.forName(keystoreProviderClass);
        if (!Provider.class.isAssignableFrom(ksProviderClass)) {
          throw new ParameterException("Keystore Provider class "
                                       + keystoreProviderClass
                                       + " not subclass of "
                                       + Provider.class.getName());
        }
        Provider ksProvider;
        if (keystoreProviderArg != null) {
          // Single-arg Provider constructor
          ksProvider = (Provider) ksProviderClass.getConstructor(String.class).newInstance(keystoreProviderArg);
        } else {
          // No-arg Provider constructor
          ksProvider = (Provider) ksProviderClass.getConstructor().newInstance();
        }
        ks = KeyStore.getInstance(ksType, ksProvider);
      } else {
        // Use the highest-priority Provider which offers the requested KeyStore type
        ks = KeyStore.getInstance(ksType);
      }

View on GitHub (pinned to e4df245d82)