Skip to content

SDK Troubleshooting Guide

Common issues when using the AnkaSecure Java SDK and their solutions.


Connection Issues

Connection Refused

Symptom:

java.net.ConnectException: Connection refused

Causes: - API endpoint URL incorrect - Firewall blocking outbound HTTPS (port 443) - Network connectivity issues

Solutions:

  1. Verify API endpoint:

    // ✅ CORRECT
    ClientConfig config = ClientConfig.builder()
        .baseUrl("https://api.ankasecure.com")  // Note: HTTPS, no trailing slash
        .build();
    
    // ❌ WRONG
    .baseUrl("http://api.ankasecure.com/")  // Wrong: HTTP instead of HTTPS
    

  2. Test connectivity:

    curl -I https://api.ankasecure.com/api/v1/public/health
    # Expected: HTTP/2 200
    

  3. Check firewall: Allow outbound HTTPS to *.ankasecure.com port 443


Connection Timeout

Symptom:

java.net.SocketTimeoutException: Read timed out

Causes: - Network latency too high - Default timeout too short (10 seconds) - Server overloaded (rare)

Solutions:

  1. Increase timeout:

    ClientConfig config = ClientConfig.builder()
        .baseUrl("https://api.ankasecure.com")
        .apiKey(apiKey)
        .connectionTimeout(30000)  // 30 seconds (default: 10s)
        .readTimeout(60000)  // 60 seconds (default: 30s)
        .build();
    

  2. Check network latency:

    ping api.ankasecure.com
    # Latency should be <200ms for good performance
    


SSL Certificate Validation Failed

Symptom:

javax.net.ssl.SSLHandshakeException: unable to find valid certification path

Causes: - Outdated CA certificates in JVM - Corporate proxy intercepting TLS (MITM)

Solutions:

  1. Update JVM (recommended):

    java -version  # Update to Java 17+ for latest CA certs
    

  2. Update CA certificates:

    # Ubuntu/Debian
    sudo apt-get update && sudo apt-get install ca-certificates
    
    # RHEL/CentOS
    sudo yum update ca-certificates
    

  3. If behind corporate proxy with custom CA:

    # Import corporate CA cert to JVM truststore
    keytool -import -trustcacerts -alias corporate-ca \
      -file corporate-ca.crt \
      -keystore $JAVA_HOME/lib/security/cacerts \
      -storepass changeit
    

DON'T: Disable certificate validation (insecure):

// ❌ NEVER DO THIS IN PRODUCTION
config.setValidateCertificates(false);  // SECURITY RISK!


Authentication Issues

401 Unauthorized

Symptom:

{
  "error": "AUTH_001",
  "message": "Token validation failed: token expired"
}

Causes: - API key invalid or expired - JWT token expired (1-hour lifetime) - Wrong tenant ID

Solutions:

  1. Verify API key:

    // Check API key copied correctly (no extra spaces/newlines)
    String apiKey = System.getenv("ANKASECURE_API_KEY").trim();
    

  2. Check tenant ID:

    // Verify tenant ID matches your tenant
    String tenantId = System.getenv("ANKASECURE_TENANT_ID").trim();
    

  3. Test authentication:

    curl https://api.ankasecure.com/api/v1/key-management/keys \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "X-Tenant-ID: YOUR_TENANT_ID"
    
    # Expected: 200 OK (not 401)
    

  4. For JWT tokens: Implement token refresh

    // Refresh token before expiration
    if (isTokenExpiringSoon(token)) {
        token = client.refreshToken(refreshToken);
    }
    


403 Forbidden

Symptom:

{
  "error": "AUTH_003",
  "message": "Access denied: insufficient permissions"
}

Causes: - User/application lacks required permissions - Trying to access another tenant's resources - Key belongs to different tenant

Solutions:

  1. Verify permissions: Check user role in Admin Console (Tenant Admin, Application Admin, User)

  2. Verify tenant ownership:

    // Ensure key belongs to your tenant
    KeyResponse key = client.getKey("some-key-id");
    assertEquals(tenantId, key.getTenantId());
    

  3. Check RBAC: Contact tenant admin to grant permissions


Cryptographic Errors

422 Unprocessable Entity (Crypto Error)

Symptom:

{
  "error": "CRYPTO_001",
  "message": "Ciphertext integrity check failed"
}

Causes: - Ciphertext corrupted during transmission - Ciphertext modified (integrity violation) - Wrong decryption key used

Solutions:

  1. Verify ciphertext integrity:

    // Check ciphertext not truncated
    String ciphertext = encrypted.getCiphertext();
    assertTrue(ciphertext.length() > 100, "Ciphertext seems truncated");
    

  2. Use correct key for decryption:

    // AnkaSecure automatically selects key (from JWE header)
    // But verify key exists and is active
    KeyResponse key = client.getKey(keyId);
    assertEquals("ACTIVE", key.getStatus());
    

  3. Check for encoding issues:

    // ✅ CORRECT: Use Base64 for plaintext
    String plaintext = Base64.getEncoder().encodeToString(data.getBytes());
    
    // ❌ WRONG: Plain string (not Base64)
    String plaintext = data;  // Will cause encoding issues
    


Key Not Found (404)

Symptom:

{
  "error": "KEY_001",
  "message": "Key not found: my-key-123"
}

Causes: - Key ID doesn't exist - Typo in key ID (case-sensitive) - Key belongs to different tenant

Solutions:

  1. List available keys:

    List<KeyResponse> keys = client.listKeys();
    keys.forEach(key -> System.out.println("Available: " + key.getKeyId()));
    

  2. Verify key ID (case-sensitive):

    // ❌ WRONG
    .keyId("My-Key-123")  // Capital M
    
    // ✅ CORRECT
    .keyId("my-key-123")  // Lowercase matches created key
    

  3. Check tenant: Ensure key created in same tenant as API key


Performance Issues

Slow Encryption (>500ms for 5 MB)

Symptom: Encryption takes significantly longer than benchmarks

Causes: - Network latency (high ping to API) - Creating new client per request (connection overhead) - Using slow algorithm (Classic McEliece, SLH-DSA-S)

Solutions:

  1. Check network latency:

    ping api.ankasecure.com
    # Should be <100ms for good performance
    

  2. Verify client reuse:

    // ✅ GOOD: Reuse client (singleton)
    private final AnkaSecureClient client;  // Injected once
    
    // ❌ BAD: New client every time
    AnkaSecureClient client = new AnkaSecureClient(config);  // DON'T
    

  3. Choose faster algorithm:

    // If using Classic McEliece (28 MB/s), switch to:
    KeyGenerationRequest fastKey = KeyGenerationRequest.builder()
        .algorithm("ML-KEM-768")  // 82 MB/s (3x faster)
        .build();
    

See performance optimization →


Out of Memory (Large Files)

Symptom:

java.lang.OutOfMemoryError: Java heap space

Causes: - Using compact API for files >5 MB (loads entire file into memory) - JVM heap size too small

Solutions:

  1. Use streaming API for large files:

    // ✅ CORRECT: Streaming for >5 MB
    client.streamEncrypt(streamRequest);
    
    // ❌ WRONG: Compact API for large files
    String largeFile = new String(Files.readAllBytes(path));  // OOM!
    client.encrypt(EncryptRequest.builder().plaintext(largeFile).build());
    

  2. Increase JVM heap (if needed):

    java -Xmx4g -jar your-application.jar  # 4 GB heap
    

See streaming API documentation →


Dependency Conflicts

NoSuchMethodError or ClassNotFoundException

Symptom:

java.lang.NoSuchMethodError: okhttp3.OkHttpClient.Builder.build()

Causes: - Version conflict with OkHttp (SDK uses 4.12.0) - Version conflict with Gson (SDK uses 2.10.1)

Solutions:

  1. Exclude conflicting dependencies:

    <dependency>
        <groupId>co.ankatech</groupId>
        <artifactId>ankasecure-sdk</artifactId>
        <version>3.0.0</version>
        <exclusions>
            <exclusion>
                <groupId>com.squareup.okhttp3</groupId>
                <artifactId>okhttp</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
    <!-- Use your preferred OkHttp version -->
    <dependency>
        <groupId>com.squareup.okhttp3</groupId>
        <artifactId>okhttp</artifactId>
        <version>4.12.0</version>
    </dependency>
    

  2. Check dependency tree:

    mvn dependency:tree | grep okhttp
    # Verify only one OkHttp version
    


Common SDK Exceptions

AnkaSecureException

Base exception for all SDK errors:

try {
    client.encrypt(request);
} catch (AnkaSecureException e) {
    System.err.println("Error Code: " + e.getErrorCode());  // e.g., "CRYPTO_001"
    System.err.println("Message: " + e.getMessage());
    System.err.println("HTTP Status: " + e.getHttpStatus());  // e.g., 422
    System.err.println("Trace ID: " + e.getTraceId());  // For support
}

Common Error Codes: - AUTH_001: Authentication failed (401) - KEY_001: Key not found (404) - CRYPTO_001: Cryptographic operation failed (422) - RATE_001: Rate limit exceeded (429) - QUOTA_001: Monthly quota exceeded (402)

See complete error catalog →


RateLimitException

Thrown when rate limit exceeded:

try {
    client.encrypt(request);
} catch (RateLimitException e) {
    int retryAfter = e.getRetryAfter();  // Seconds to wait
    System.err.println("Rate limited. Retry after: " + retryAfter + "s");

    // Implement backoff
    Thread.sleep(retryAfter * 1000);
    client.encrypt(request);  // Retry
}

ValidationException

Thrown when request validation fails:

try {
    client.generateKey(request);
} catch (ValidationException e) {
    List<ValidationError> errors = e.getValidationErrors();
    errors.forEach(error -> {
        System.err.println("Field: " + error.getField());
        System.err.println("Issue: " + error.getIssue());
        System.err.println("Received: " + error.getReceived());
    });
}

// Example output:
// Field: algorithm
// Issue: Must be one of: ML-KEM-512, ML-KEM-768, ML-KEM-1024
// Received: INVALID_ALGO

Debugging Tips

Enable Debug Logging

Configure SDK logging:

import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;

// Enable debug logs for AnkaSecure SDK
Logger sdkLogger = (Logger) LoggerFactory.getLogger("co.ankatech.ankasecure");
sdkLogger.setLevel(Level.DEBUG);

Or via logback.xml:

<configuration>
    <logger name="co.ankatech.ankasecure" level="DEBUG"/>
    <logger name="okhttp3" level="DEBUG"/>  <!-- HTTP client logs -->
</configuration>

Debug Output:

DEBUG co.ankatech.ankasecure.client - Request: POST /api/v1/crypto/encrypt
DEBUG co.ankatech.ankasecure.client - Headers: Authorization=Bearer ask_***, X-Tenant-ID=acme-corp
DEBUG co.ankatech.ankasecure.client - Body: {"keyId":"my-key","plaintext":"..."}
DEBUG co.ankatech.ankasecure.client - Response: 200 OK
DEBUG co.ankatech.ankasecure.client - Latency: 124ms


Extract Correlation ID

Use correlation ID for support:

try {
    client.encrypt(request);
} catch (AnkaSecureException e) {
    String traceId = e.getTraceId();  // Correlation ID
    System.err.println("Error occurred. Trace ID: " + traceId);
    System.err.println("Include this ID when contacting support");

    // Log for troubleshooting
    log.error("Encryption failed [traceId={}]", traceId, e);
}

Contact Support: Provide trace ID for faster resolution


Need Help?


Documentation Version: 3.0.0 Last Updated: 2025-12-26