ory/hydra · error

header, body and signature must all be set

Error message

header, body and signature must all be set

What it means

getTokenSignature splits a JWS compact-serialization token on '.' and requires exactly three parts: header, body, signature. Any token with a different number of dot-separated segments is malformed and fails with this error before the signature is extracted.

Source

Thrown at fosite/token/jwt/jwt.go:177

}

func decodeToken(token string, verificationKey interface{}) (*Token, error) {
	keyFunc := func(*Token) (interface{}, error) { return verificationKey, nil }
	return ParseWithClaims(token, MapClaims{}, keyFunc)
}

func validateToken(tokenStr string, verificationKey interface{}) (string, error) {
	_, err := decodeToken(tokenStr, verificationKey)
	if err != nil {
		return "", err
	}
	return getTokenSignature(tokenStr)
}

func getTokenSignature(token string) (string, error) {
	split := strings.Split(token, ".")
	if len(split) != 3 {
		return "", errors.New("header, body and signature must all be set")
	}
	return split[2], nil
}

func hashSHA256(in []byte) ([]byte, error) {
	hash := sha256.New()
	_, err := hash.Write(in)
	if err != nil {
		return []byte{}, errorsx.WithStack(err)
	}
	return hash.Sum([]byte{}), nil
}

func assign(a, b map[string]interface{}) map[string]interface{} {
	for k, w := range b {
		if _, ok := a[k]; ok {
			continue
		}

View on GitHub (pinned to 4174065ffb)

Solutions

  1. Ensure only JWTs produced by the fosite jwt.Signer (three dot-separated parts) are passed to these functions
  2. Check upstream code that a non-empty, non-opaque token is forwarded — opaque tokens belong to HMAC strategies, not JWT validation
  3. Log/verify the token shape (strings.Count(token, ".") == 2) before calling GetSignature

Example fix

// before
sig, err := getTokenSignature(opaqueToken)
// after
if strings.Count(token, ".") != 2 {
    return errors.New("not a JWT")
}
sig, err := getTokenSignature(token)
Defensive patterns

Strategy: type-guard

Type guard

func isJWT(token string) bool {
    parts := strings.Split(token, ".")
    return len(parts) == 3 && parts[0] != "" && parts[1] != ""
}

Try / catch

sig, err := getTokenSignature(token)
if err != nil && err.Error() == "header, body and signature must all be set" {
    // treat token as opaque or reject request
}

Prevention

When it happens

Trigger: Calling GetSignature, generateToken, or validateToken with a token string that does not have exactly three dot-separated segments — e.g. nil/empty token, an opaque token passed where a JWT is expected, or a manually truncated token.

Common situations: Passing an opaque access token to a JWT-signing/verification function; a token truncated by a header size limit or log-strip middleware; constructing a JWT without a signature part in custom code.

Related errors


AI-assisted analysis of ory/hydra@4174065ffb (2026-09-03). Data as JSON: /api/errors/f67aaf11fa2d4bf1. Report an issue: GitHub.