aaif-goose/goose · error
EC key missing curve parameters. Convert to PKCS#8: openssl
Error message
EC key missing curve parameters. Convert to PKCS#8: openssl pkey -in key.pem -out key-pkcs8.pem
What it means
The SEC1 EC private key parsed successfully, but ec_key.parameters.named_curve() returned None, meaning the key does not identify its curve by a standard named-curve OID (prime256v1, secp384r1, ...). goose's EC-to-PKCS#8 re-wrapper needs a named curve to build the PKCS#8 AlgorithmIdentifier, so it refuses the key and tells you to convert it with openssl pkey.
Source
Thrown at crates/goose-providers/src/api_client.rs:183
pem::parse(key_pem_str).map_err(|e| anyhow::anyhow!("Failed to parse PEM key: {}", e))?;
match parsed.tag() {
"PRIVATE KEY" => Ok(key_pem_str.to_string()),
"RSA PRIVATE KEY" => {
let info = pkcs8::PrivateKeyInfo::new(pkcs1::ALGORITHM_ID, parsed.contents());
let der_bytes = info
.to_der()
.map_err(|e| anyhow::anyhow!("Failed to encode PKCS#8: {}", e))?;
Ok(pem::encode(&pem::Pem::new("PRIVATE KEY", der_bytes)))
}
"EC PRIVATE KEY" => {
let ec_key = sec1::EcPrivateKey::from_der(parsed.contents())
.map_err(|e| anyhow::anyhow!("Failed to parse EC key: {}", e))?;
let curve_oid = ec_key
.parameters
.and_then(|p| p.named_curve())
.ok_or_else(|| {
anyhow::anyhow!(
"EC key missing curve parameters. Convert to PKCS#8: \
openssl pkey -in key.pem -out key-pkcs8.pem"
)
})?;
let algorithm = pkcs8::AlgorithmIdentifierRef {
oid: sec1::ALGORITHM_OID,
parameters: Some((&curve_oid).into()),
};
let info = pkcs8::PrivateKeyInfo::new(algorithm, parsed.contents());
let der_bytes = info
.to_der()
.map_err(|e| anyhow::anyhow!("Failed to encode PKCS#8: {}", e))?;
Ok(pem::encode(&pem::Pem::new("PRIVATE KEY", der_bytes)))
}
tag => Err(anyhow::anyhow!(
"Unsupported key format '{}'. Expected PKCS#8, PKCS#1, or SEC1. \
Convert with: openssl pkey -in key.pem -out key-pkcs8.pem",
tagView on GitHub (pinned to 3810898a74)
Solutions
- Convert the key so the curve becomes a named OID: openssl pkey -in key.pem -out key-pkcs8.pem (PKCS#8 also bypasses this whole conversion path)
- If openssl also refuses, regenerate the key on a standard named curve: openssl ecparam -name prime256v1 -genkey -noout -out key.pem
- Verify the curve is representable: openssl ec -in key.pem -noout -text should show 'ASN1 OID: prime256v1' (or secp384r1/secp521r1)
Example fix
# before: parameters omitted or explicit openssl ec -in old-key.pem -noout -text # shows no 'ASN1 OID' line # after openssl pkey -in old-key.pem -out key-pkcs8.pem # named curve + PKCS#8 wrapper
Defensive patterns
Strategy: validation
Validate before calling
fn has_named_curve(path: &str) -> anyhow::Result<()> {
let out = std::process::Command::new("openssl")
.args(["ec", "-in", path, "-noout", "-text"])
.output()?;
let text = String::from_utf8_lossy(&out.stdout);
anyhow::ensure!(out.status.success() && text.contains("ASN1 OID:"),
"key lacks a named curve; openssl pkey -in {path} -out {path}.pkcs8");
Ok(())
} Try / catch
match build_client_with_mtls(cert, key) {
Err(e) if e.to_string().contains("missing curve parameters") => {
// auto-remediate once: convert with `openssl pkey`, retry, else surface the hint
}
r => r?,
} Prevention
- Prefer named curves (prime256v1/secp384r1) when generating keys for mTLS
- Standardize on PKCS#8 output so the SEC1 conversion path never executes
- Document in your onboarding that HSM/exotic exports must be re-wrapped via openssl pkey before use
When it happens
Trigger: A '-----BEGIN EC PRIVATE KEY-----' mTLS key whose parameters use an explicit/encoded curve (generated by very old OpenSSL, BouncyCastle, or an HSM export) or omit the curve entirely, supplied via TlsConfig::with_client_cert_and_key under the native-tls feature.
Common situations: Corporate PKI or IoT device certificates issuing keys with explicit parameters for curve agility; keys moved between crypto libraries that re-encode parameters; exotic curves (brainpool via explicit encoding) that have no registered named-curve OID in the sec1 crate's table.
Related errors
- Failed to parse EC key: {}
- Unsupported key format '{}'. Expected PKCS#8, PKCS#1, or SEC
- Failed to parse PEM key: {}
- Failed to encode PKCS#8: {}
- Failed to create identity from cert and key: {}
AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16).
Data as JSON: /api/errors/f51e9682e932d898.
Report an issue: GitHub.