grpc/grpc-java · error · UnsupportedOperationException

Signature Algorithm %d is not supported.

Error message

Signature Algorithm %d is not supported.

What it means

convertOpenSslSignAlgToS2ASignAlg translates an OpenSSL signature-algorithm ID (as reported by the TLS stack during signing) into the S2A handshaker's SignatureAlgorithm proto enum via a lookup map. When the OpenSSL algorithm has no mapping, it throws UnsupportedOperationException — the S2A client cannot express that signature algorithm to the S2A service.

Source

Thrown at s2a/src/main/java/io/grpc/s2a/internal/handshaker/S2APrivateKeyMethod.java:94

  private S2APrivateKeyMethod(S2AStub stub, Optional<S2AIdentity> localIdentity) {
    this.stub = stub;
    this.localIdentity = localIdentity;
  }

  /**
   * Converts the signature algorithm to an enum understood by S2A.
   *
   * @param signatureAlgorithm the int representation of the signature algorithm define by {@code
   *     OpenSslPrivateKeyMethod}.
   * @return the signature algorithm enum defined by S2A proto.
   * @throws UnsupportedOperationException if the algorithm is not supported by S2A.
   */
  @VisibleForTesting
  static SignatureAlgorithm convertOpenSslSignAlgToS2ASignAlg(int signatureAlgorithm) {
    SignatureAlgorithm sig = OPENSSL_TO_S2A_SIGNATURE_ALGORITHM_MAP.get(signatureAlgorithm);
    if (sig == null) {
      throw new UnsupportedOperationException(
          String.format("Signature Algorithm %d is not supported.", signatureAlgorithm));
    }
    return sig;
  }

  /**
   * Signs the input bytes by sending the request to the S2A srever.
   *
   * @param engine not used.
   * @param signatureAlgorithm the {@link OpenSslPrivateKeyMethod}'s signature algorithm
   *     representation
   * @param input the bytes to be signed.
   * @return the signature of the {@code input}.
   * @throws IOException if the connection to the S2A server is corrupted.
   * @throws InterruptedException if the connection to the S2A server is interrupted.
   * @throws S2AConnectionException if the response from the S2A server does not contain valid data.
   */
  @Override

View on GitHub (pinned to 64daddc1f3)

Solutions

  1. Upgrade the gRPC s2a library so OPENSSL_TO_S2A_SIGNATURE_ALGORITHM_MAP includes the algorithm (check the @VisibleForTesting map contents).
  2. Switch the certificate/key to a supported type, e.g. RSA (PKCS#1) or ECDSA P-256, avoiding EdDSA/RSA-PSS-only certs.
  3. Restrict the TLS cipher suites/signature algorithms negotiated so only mapped algorithms are offered.
  4. Log the offending signatureAlgorithm int and compare against the map to confirm which algorithm is unsupported.

Example fix

// before
KeyPair kp = generateEd25519KeyPair(); // algorithm unmapped
// after
KeyPair kp = generateRsa2048KeyPair(); // RSA sig alg supported by S2A map
Defensive patterns

Strategy: try-catch

Validate before calling

static boolean isSupportedSigAlg(int opensslAlgId) {
  return opensslAlgId == /* RSA */ NID_sha256WithRSAEncryption
      || opensslAlgId == /* ECDSA */ NID_ecdsa_with_SHA256; // mirror the client's map
}

Try / catch

try {
  byte[] sig = keyMethod.sign(engine, input);
} catch (UnsupportedOperationException e) {
  failHandshake("unsupported signature algorithm: " + e.getMessage());
}

Prevention

When it happens

Trigger: During an S2A-offloaded TLS handshake, s2aSignatureAlgorithm receives a signatureAlgorithm int from the SSL engine (e.g. Ed25519/Ed448, RSA-PSS variants, or a newer algorithm) that is absent from OPENSSL_TO_S2A_SIGNATURE_ALGORITHM_MAP.

Common situations: Using a cipher suite or certificate key type (EdDSA, RSA-PSS) the bundled S2A handshaker proto doesn't support; mismatched BoringSSL/OpenSSL version producing algorithm IDs the map doesn't cover; older s2a client library with a smaller map.

Related errors


AI-assisted analysis of grpc/grpc-java@64daddc1f3 (2026-09-08). Data as JSON: /api/errors/722cd590e2e72599. Report an issue: GitHub.