{"record":{"id":"eeb85f64140a4ed8","repo":"ory/kratos","slug":"private-key-decoding-failed","errorCode":null,"errorMessage":"Private key decoding failed","messagePattern":"Private key decoding failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"selfservice/strategy/oidc/provider_apple.go","lineNumber":53,"sourceCode":"\treturn &ProviderApple{\n\t\tProviderGenericOIDC: &ProviderGenericOIDC{\n\t\t\tconfig: config,\n\t\t\treg:    reg,\n\t\t},\n\t\tJWKSUrl: \"https://appleid.apple.com/auth/keys\",\n\t}\n}\n\nfunc (a *ProviderApple) newClientSecret() (string, error) {\n\t// decode the pem format\n\tblock, _ := pem.Decode([]byte(a.config.PrivateKey))\n\tif block == nil || block.Type != \"PRIVATE KEY\" {\n\t\treturn \"\", errors.New(\"failed to decode PEM block containing private key\")\n\t}\n\n\tparsedKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)\n\tif err != nil {\n\t\treturn \"\", errors.Wrap(err, \"Private key decoding failed\")\n\t}\n\tprivateKey, ok := parsedKey.(*ecdsa.PrivateKey)\n\tif !ok {\n\t\treturn \"\", errors.New(\"Private key is not ecdsa key\")\n\t}\n\n\tnow := time.Now()\n\texpirationTime := time.Now().Add(5 * time.Minute)\n\n\tappleToken := jwt.NewWithClaims(jwt.SigningMethodES256,\n\t\tjwt.RegisteredClaims{\n\t\t\tAudience:  []string{\"https://appleid.apple.com\"},\n\t\t\tExpiresAt: jwt.NewNumericDate(expirationTime),\n\t\t\tIssuedAt:  jwt.NewNumericDate(now),\n\t\t\tIssuer:    a.config.TeamId,\n\t\t\tSubject:   a.config.ClientID,\n\t\t})\n\tappleToken.Header[\"kid\"] = a.config.PrivateKeyId","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/ory/kratos/blob/b86338da04a040247a07f46100a86dcfb3875909/selfservice/strategy/oidc/provider_apple.go#L35-L71","documentation":"Apple Sign-In uses a private key (client_secret generated as a signed ES256 JWT). newClientSecret parses the configured PEM private key with x509.ParsePKCS8PrivateKey; this error wraps a failure to parse the PKCS#8 DER bytes inside the PEM block. The PEM was decodable but its contents are not a valid PKCS#8 private key.","triggerScenarios":"Calling newClientSecret (via the oauth2 flow) when the apple private_key config value contains a PEM \"PRIVATE KEY\" block whose DER payload fails x509.ParsePKCS8PrivateKey — e.g. corrupted base64, wrong key format (PKCS#1 / SEC1 instead of PKCS#8), or truncated key.","commonSituations":"Copying an Apple .p8 key with extra whitespace/newlines mangled during copy-paste, env-var round-tripping stripping newlines (\\n not interpreted), or using a key exported in a non-PKCS8 format.","solutions":["Re-download the .p8 key from the Apple Developer portal and re-encode it as proper PKCS#8 PEM (openssl pkcs8 -topk8 -nocrypt -in key.pem).","If configured via environment variable, ensure newlines are preserved (use \\n escapes the config loader understands or a file secret).","Verify with `openssl pkey -in key.pem -noout` that the key parses outside the app.","Confirm the PEM block type is \"PRIVATE KEY\" (PKCS#8), not \"EC PRIVATE KEY\" or \"RSA PRIVATE KEY\"."],"exampleFix":"// before: APPLE_PRIVATE_KEY=\"-----BEGIN PRIVATE KEY-----\\nMIGT...\" (literal backslash-n)\n// after:  load the key from a file/secret so real newlines are preserved","handlingStrategy":"validation","validationCode":"pemBytes := []byte(privateKey)\nblock, _ := pem.Decode(pemBytes)\nif block == nil || block.Type != \"PRIVATE KEY\" { return errors.New(\"key is not PKCS#8 PEM\") }\nif _, err := x509.ParsePKCS8PrivateKey(block.Bytes); err != nil { return fmt.Errorf(\"invalid PKCS#8 key: %w\", err) }","typeGuard":"func isPKCS8ECDSAPrivateKey(pemStr string) (*ecdsa.PrivateKey, bool) {\n  block, _ := pem.Decode([]byte(pemStr))\n  if block == nil || block.Type != \"PRIVATE KEY\" { return nil, false }\n  k, err := x509.ParsePKCS8PrivateKey(block.Bytes)\n  if err != nil { return nil, false }\n  ek, ok := k.(*ecdsa.PrivateKey)\n  return ek, ok\n}","tryCatchPattern":null,"preventionTips":["Store Apple .p8 keys as file-backed secrets, not inline env vars, to preserve newlines.","Convert keys to PKCS#8 with `openssl pkcs8 -topk8 -nocrypt` before configuring.","Validate the key parses with `openssl pkey -noout` at deploy time."],"tags":["oidc","apple","private-key","pem","configuration"],"backgroundTag":"invalid-config-value","analyzedSha":"b86338da04a040247a07f46100a86dcfb3875909","analyzedAt":"2026-09-07T15:58:15.934Z","contentChangedAt":"2026-09-07T15:58:15.934Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}