dgraph-io/dgraph · error
unexpected signing method in token: %v
Error message
unexpected signing method in token: %v
What it means
The key-lookup callback in jwt.Parse rejects tokens whose header 'alg' does not match the configured ACL algorithm (WorkerConfig.AclJwtAlg.Alg()). This is an algorithm-confusion defense: a token signed with a different (possibly weaker) algorithm must not be accepted. The error includes the token's alg header value.
Source
Thrown at x/jwt_helper.go:36
)
// MaybeKeyToBytes converts the x.Sensitive type into []byte if the type of interface really
// is x.Sensitive. We keep the type x.Sensitive for private and public keys so that it
// doesn't get printed into the logs but the type the JWT library needs is []byte.
func MaybeKeyToBytes(k interface{}) interface{} {
if kb, ok := k.(Sensitive); ok {
return []byte(kb)
}
return k
}
func ParseJWT(jwtStr string) (jwt.MapClaims, error) {
token, err := jwt.Parse(jwtStr, func(token *jwt.Token) (interface{}, error) {
if WorkerConfig.AclJwtAlg == nil {
return nil, errors.Errorf("ACL is disabled")
}
if token.Method.Alg() != WorkerConfig.AclJwtAlg.Alg() {
return nil, errors.Errorf("unexpected signing method in token: %v", token.Header["alg"])
}
return MaybeKeyToBytes(WorkerConfig.AclPublicKey), nil
})
if err != nil {
// This is for backward compatibility in clients
if errors.Is(err, jwt.ErrTokenExpired) {
err = errors.Wrap(errTokenExpired, jwt.ErrTokenInvalidClaims.Error())
}
return nil, errors.Wrapf(err, "unable to parse jwt token")
}
claims, ok := token.Claims.(jwt.MapClaims)
if !ok || !token.Valid {
return nil, errors.Errorf("claims in jwt token is not map claims")
}
return claims, nil
}
View on GitHub (pinned to 759e242be6)
Solutions
- Re-issue the access JWT signed with the algorithm the server expects (match WorkerConfig.AclJwtAlg).
- Align server config: set AclJwtAlg to the algorithm actually used to sign your tokens.
- Check the token issuer/pipeline — ensure you are sending the ACL access token, not some other JWT.
- Read the alg value in the error message and compare against your signing code's algorithm; fix whichever side is wrong.
Example fix
// before: client signs with RS256 while server expects HS256 alg := jwt.SigningMethodRS256 // after: use the configured algorithm tok := jwt.NewWithClaims(WorkerConfig.AclJwtAlg, claims)
Defensive patterns
Strategy: validation
Validate before calling
parts := strings.Split(token, ".")
if len(parts) != 3 { return errors.New("malformed jwt") }
hdr, _ := base64.RawURLEncoding.DecodeString(parts[0])
var h struct{ Alg string `json:"alg"` }
json.Unmarshal(hdr, &h)
if h.Alg != WorkerConfig.AclJwtAlg.Alg() {
return fmt.Errorf("token alg %s does not match configured %s", h.Alg, WorkerConfig.AclJwtAlg.Alg())
} Type guard
func algMatches(token *jwt.Token) bool {
return WorkerConfig.AclJwtAlg != nil && token.Method.Alg() == WorkerConfig.AclJwtAlg.Alg()
} Prevention
- Always sign client tokens with the same algorithm configured server-side (AclJwtAlg).
- Never hardcode signing methods; read them from shared config.
- Never accept 'alg: none' or let the token header choose the algorithm.
- Add an integration test that mints a token and parses it with x.ParseJWT before deploys.
When it happens
Trigger: jwt.Parse is given a token whose alg header (e.g. RS256, none, HS256) differs from WorkerConfig.AclJwtAlg.Alg() — e.g. client signs JWTs with the wrong algorithm or a token from a different system is presented.
Common situations: Client side regenerated keys with a different alg after a server upgrade; mixing tokens from a non-ACL system; maliciously crafted tokens probing for algorithm confusion; config where server expects HS256 but clients use RS256.
Related errors
- unexpected signing method: Expected %s Found %s
- expecting either JWKUrl or JWKUrls, both were given
- expecting either JWKUrl/JWKUrls or (VerificationKey, Algo),
- required field missing in Dgraph.Authorization:%s
- invalid Bearer-formatted header value for JWT (%s)
AI-assisted analysis of dgraph-io/dgraph@759e242be6 (2026-09-01).
Data as JSON: /api/errors/d5365c273f514a0b.
Report an issue: GitHub.