Missing Private Key
URI: https://docs.ankatech.co/errors/missing-private-key HTTP Status: 422 Unprocessable Entity
When You See This
Your PKCS#7/CMS file is valid and supported, but the conversion requires a private key that has not been imported to the keystore. The system identified the signer or recipient certificate but cannot find the matching private key.
Common Causes
- Private key not imported – The PKCS#12 (.p12, .pfx) file containing the private key was never imported
- Wrong decryptionKid specified – You provided a kid that exists but doesn't match the recipient certificate
- Certificate mismatch – The imported private key has a different certificate than expected
- Kid not found – The specified decryptionKid doesn't exist in the keystore
Response Example
{
"type": "https://docs.ankatech.co/errors/missing-private-key",
"title": "Missing Private Key",
"status": 422,
"detail": "Required private key not found for recipient with issuerDN: CN=John Doe,O=AnkaTech,C=US",
"instance": "/api/migration/convert-pkcs7-to-jose",
"timestamp": 1738117563,
"extensions": {
"errorCode": "MISSING_RECIPIENT_PRIVATE_KEY",
"issuerDN": "CN=John Doe,O=AnkaTech,C=US",
"serialNumber": "0x4A3F2E1D5B6C7A8B",
"importEndpoint": "POST /api/migration/keystores",
"requiredKeyType": "RSA or EC private key with certificate chain"
}
}
Error Codes
| Code | Description | Required Key |
|---|---|---|
MISSING_SIGNER_PRIVATE_KEY | SignedData signer key not found | Signing private key |
MISSING_RECIPIENT_PRIVATE_KEY | EnvelopedData recipient key not found | Decryption private key |
How to Resolve
Step 1: Analyze Your PKCS#7 File
Use the analyze endpoint to identify required keys:
POST /api/migration/analyze-pkcs7
Content-Type: application/json
{
"pkcs7Data": "<base64-encoded-pkcs7>",
"validateCertificates": false
}
The response shows:
{
"recipients": [
{
"issuerDN": "CN=John Doe,O=AnkaTech,C=US",
"serialNumber": "0x4A3F2E1D5B6C7A8B",
"keyEncryptionAlgorithm": "RSA"
}
],
"recommendations": {
"requiredKeys": [
{
"purpose": "decryption",
"issuerDN": "CN=John Doe,O=AnkaTech,C=US",
"serialNumber": "0x4A3F2E1D5B6C7A8B",
"importHint": "Use POST /api/migration/keystores to import matching RSA private key and certificate"
}
]
}
}
Step 2: Import the Required Private Key
Import the PKCS#12 file containing the private key and certificate chain:
POST /api/migration/keystores
Content-Type: application/json
{
"kid": "my-recipient-key",
"password": "p12password",
"keystoreContent": "<base64-encoded-p12-file>",
"kidStrategy": "AUTO",
"validationMode": "STRICT"
}
Important: The certificate in the PKCS#12 must match:
- Issuer DN: Must be identical (order-independent)
- Serial Number: Must match exactly
Step 3: Verify Import
Check that the key was imported successfully:
Response should include certificate metadata matching the PKCS#7 recipient.
Step 4: Retry Conversion
Now convert the PKCS#7 file with the correct decryptionKid:
POST /api/migration/convert-pkcs7-to-jose
Content-Type: application/json
{
"pkcs7Data": "<base64-encoded-pkcs7>",
"decryptionKid": "my-recipient-key",
"serialization": "AUTO",
"targetFormat": "AUTO"
}
Certificate Matching Rules
The system matches private keys using:
- Issuer Distinguished Name (DN)
- Order-independent comparison
- RFC 2253 canonical format
-
Example:
CN=Test,O=AnkaTech,C=USmatchesC=US,O=AnkaTech,CN=Test -
Serial Number
- Hexadecimal format with 0x prefix
- Case-insensitive
- Example:
0x4A3Fmatches0x4a3f
Troubleshooting
Error: "Decryption key mismatch"
Your imported key exists but doesn't match the recipient certificate:
Check issuer DN:
# Extract from PKCS#7 analysis response
"issuerDN": "CN=John Doe,O=AnkaTech,C=US"
# Extract from imported key
GET /api/migration/keys/{kid}
Check serial number:
# Both should match exactly
PKCS#7: "serialNumber": "0x4A3F2E1D5B6C7A8B"
Imported: Compare with certificate metadata
Error: "Kid not found"
The decryptionKid you specified doesn't exist:
Error: "No certificate chain"
The imported private key doesn't have an associated certificate:
- Re-import the PKCS#12 file ensuring it contains the full certificate chain
- Use
validationMode: "IMPORT_ONLY"if certificates are expired
Best Practices
- Always analyze before converting - Use
POST /api/migration/analyze-pkcs7first - Import with certificate chain - Ensure PKCS#12 includes full chain
- Use descriptive kids - Name keys to indicate purpose (e.g., "legacy-recipient-2024")
- Keep certificates valid - Use
STRICTvalidation mode in production - Document certificate details - Store issuerDN and serial for reference