Custom JWT - invalid key type *rsa.PrivateKey. *rsa.PublicKey is required

I’m encountering some issues while trying to implement Web3Auth with custom JWT authentication in my React application. I have configured a verifier ‘tiny-auth-creator’ with JWT verifier id for sub (which represents a userId), JWK endpoint, and JWT validation fields [verified: true, aud: tt-webcreator] in the w3a dashboard.

The trouble I’m experiencing is that when calling the login function, the window gets redirected to itself with a hash parameter, and then I’m presented with different errors depending on the network I’m using:

  • For testnet and cyan, I get an error message stating: “Could not get result from torus nodes. Error occurred while verifying params unable to verify jwt token, [failed to verify jws signature: failed to verify message: invalid key type *rsa.PrivateKey. *rsa.PublicKey is required]”

  • For sapphire_devnet and sapphire_mainnet, the error message says: “Could not get result from torus nodes. Sorry, the Torus Network that powers Web3Auth is currently very busy. We will generate your key in time. Please try again later.”

I’ve verified the validity of the JWT signature against its own JWK on and am using the tkey core js sdk. My React application is based on Web3Auth’s examples on GitHub. I’m running the app on MacOSX. I generate the JWT on a Node.js server that also generates the JWK based on a secured key pair. I have a test server set up to generate and test the JWT keys.

Verifier Details:


SDK Version:

  • @tkey/default”: “^9.0.1”,

  • @tkey/security-questions”: “^9.0.0”,

  • @tkey/service-provider-torus”: “^9.0.0”,

  • @tkey/web-storage”: “^9.0.0”,

  • @web3auth/ethereum-provider”: “^5.2.0”,

  • “web3”: “^1.8.1”

Any help or insight on how to resolve these issues would be greatly appreciated.

Best Regards,

const customAuthArgs = {
  web3AuthClientId: WEB3AUTH_CLIENT_ID,
  baseUrl: window.location.origin,
  redirectPathName: 'auth',
  enableLogging: true,
  uxMode: 'redirect',
  network: 'testnet', // based on the verifier network. testnet / mainnet / cyan / sapphire_devnet / sapphire_mainnet
// Configuration of Modules
const webStorageModule = new WebStorageModule()
const securityQuestionsModule = new SecurityQuestionsModule()

// Instantiation of tKey
export const tKey = new ThresholdKey({
  modules: {
    webStorage: webStorageModule,
    securityQuestions: securityQuestionsModule,
  customAuthArgs: customAuthArgs as any,

// Init Service Provider inside the useEffect Method
  useEffect(() => {
    const init = async () => {
      // Initialization of Service Provider
      try {
        // Init is required for Redirect Flow but skip fetching sw.js and redirect.html )
        ;(tKey.serviceProvider as any).init({ skipInit: true, skipSw: true })
        if (window.location.pathname === '/auth' && window.location.hash.includes('#state')) {
          let result = await (tKey.serviceProvider as any).directWeb.getRedirectResult()
          tKey.serviceProvider.postboxKey = new BN((result.result as any).privateKey!, 'hex')
          setUser((result.result as any).userInfo)
          setOAuthShare((result.result as any).privateKey)
      } catch (error) {
    const ethProvider = async () => {
      const ethereumPrivateKeyProvider = new EthereumPrivateKeyProvider({
        config: {
				pass the chain config that you want to connect with
				all chainConfig fields are required.
          chainConfig: {
            chainId: '0x5',
            rpcTarget: '',
            displayName: 'Goerli Testnet',
            blockExplorer: '',
            ticker: 'ETH',
            tickerName: 'Ethereum',
			pass user's private key here.
			after calling setupProvider, we can use
      if (privateKey) {
        await ethereumPrivateKeyProvider.setupProvider(privateKey)
  }, [privateKey])

const triggerLogin = async () => {
    if (!tKey) {
      uiConsole('tKey not initialized yet')
    let token
    try {
      token = await getIdToken()
    } catch (err) {
    try {
      console.log({ token, userId })
      const clientId = WEB3AUTH_CLIENT_ID //'ab3002c4-aad1-4a49-8059-2c433a51f5e0'
      const loginResponse = await (tKey.serviceProvider as any).triggerLogin({
        typeOfLogin: 'jwt',
        verifier: 'tiny-auth-creator',
        verifierId: userId,
        //hash: token,
        jwtParams: {
          verifierIdField: 'sub',
          id_token: token,
      // uiConsole('Public Key : ' + loginResponse.publicAddress);
      // uiConsole('Email : ' +;

    } catch (error) {

@AceDZN Thanks for reaching out.

Your issue has been forwarded to our team and we will get back with for the updates once more information becomes available.

The JWT you are providing to the nodes fails the verification with the JWK that you deployed your login verifier with.

Can you please check the error here:

Our team are continuing to look into your issue and I will keep you updated on the progress.

Hello @AceDZN,

I have a few concerns and questions that I would like to address:

  1. The kid value differs between the id_token shared and the screenshot ( decoded) from the jwks.
  2. If tiny-auth-creator is a testnet verifier, it will only function in a testnet environment.
  3. May I know how you obtained the token?
  4. Which example are you using to guide your code? We have a few available here.

Best regards.