ory/hydra · error
square/go-jose: parse error, got '%s', '%s' and '%s'
Error message
square/go-jose: parse error, got '%s', '%s' and '%s'
What it means
LoadPublicKey tries to parse the input bytes three ways: as PEM (ParsePKIXPublicKey), as DER, and as a JWK (LoadJSONWebKey). If all three fail, it aggregates the three errors into this single parse-error message.
Source
Thrown at oryx/josex/utils.go:69
}
// Try to load SubjectPublicKeyInfo
pub, err0 := x509.ParsePKIXPublicKey(input)
if err0 == nil {
return pub, nil
}
cert, err1 := x509.ParseCertificate(input)
if err1 == nil {
return cert.PublicKey, nil
}
jwk, err2 := LoadJSONWebKey(data, true)
if err2 == nil {
return jwk, nil
}
return nil, fmt.Errorf("square/go-jose: parse error, got '%s', '%s' and '%s'", err0, err1, err2)
}
// LoadPrivateKey loads a private key from PEM/DER/JWK-encoded data.
func LoadPrivateKey(data []byte) (interface{}, error) {
input := data
block, _ := pem.Decode(data)
if block != nil {
input = block.Bytes
}
var priv interface{}
priv, err0 := x509.ParsePKCS1PrivateKey(input)
if err0 == nil {
return priv, nil
}
priv, err1 := x509.ParsePKCS8PrivateKey(input)View on GitHub (pinned to 4174065ffb)
Solutions
- Inspect err0/err1/err2 in the message — they show exactly why PEM, DER, and JWK parsing each failed
- Ensure the input is a PEM 'BEGIN PUBLIC KEY' block, raw DER SPKI bytes, or a JWK JSON object
- If you have a certificate, extract its public key first (x509 cert .PublicKey) or use a loader that accepts certificates
- If you only have a private key, derive the public key from it and pass that
- Verify the file/env value is non-empty and not truncated
Example fix
// before
data, _ := os.ReadFile("server.key") // private key PEM
jwk, err := josex.LoadPublicKey(data)
// after
data, _ := os.ReadFile("server.pub") // PEM PUBLIC KEY
jwk, err := josex.LoadPublicKey(data) Defensive patterns
Strategy: validation
Validate before calling
func looksLikePublicKey(data []byte) error {
s := strings.TrimSpace(string(data))
switch {
case strings.HasPrefix(s, "-----BEGIN PUBLIC KEY-----"),
strings.HasPrefix(s, "{\"kty\""):
return nil
case strings.HasPrefix(s, "-----BEGIN CERTIFICATE-----"):
return errors.New("got a certificate; extract the public key first")
case strings.Contains(s, "PRIVATE KEY"):
return errors.New("got a private key; LoadPublicKey needs the public key")
default:
return errors.New("input is neither PEM PUBLIC KEY nor JWK JSON")
}
} Type guard
func isPEMPublicKey(data []byte) bool {
return strings.HasPrefix(strings.TrimSpace(string(data)), "-----BEGIN PUBLIC KEY-----")
}
func isJWK(data []byte) bool {
return json.Valid(data) && strings.Contains(string(data), "\"kty\"")
} Try / catch
jwk, err := josex.LoadPublicKey(data)
if err != nil {
return fmt.Errorf("invalid public key material: %w", err)
} Prevention
- Store keys as PEM PUBLIC KEY or JWK files and name files accordingly (.pub vs .key)
- Never feed certificates where plain public keys are expected
- Check the mounted file/env var is non-empty at startup
- Log the first bytes of the input when key loading fails to spot wrong formats
When it happens
Trigger: Calling josex.LoadPublicKey with data that is none of PEM PKIX public key, DER public key, or JWK JSON — e.g. a private-key PEM, a raw base64 key, an x509 certificate instead of a public key, or truncated/garbled bytes.
Common situations: Pointing config at a private key file when a public key is required; pasting a certificate (-----BEGIN CERTIFICATE-----) instead of -----BEGIN PUBLIC KEY-----; wrong env var or file mounted empty; whitespace/BOM corruption.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- square/go-jose: parse error, got '%s', '%s', '%s' and '%s'
- invalid JWK key
- unknown algorithm %s for signing key
- unknown algorithm %s for encryption key
- invalid elliptic curve key size, this algorithm does not sup
AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03).
Data as JSON: /api/errors/f1bb6f27e3641cf3.
Report an issue: GitHub.