{"record":{"id":"5acea3cfb4ca02f0","repo":"dgraph-io/dgraph","slug":"acl-key-length-v-v-bits-for-jwt-algorithm","errorCode":null,"errorMessage":"ACL key length [%v <= %v] bits for JWT algorithm [%v]","messagePattern":"ACL key length \\[(.+?) <= (.+?)\\] bits for JWT algorithm \\[(.+?)\\]","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"x/acl_enc_keys.go","lineNumber":142,"sourceCode":"\n\tdefault:\n\t\treturn nil, nil, errors.Errorf(\"unsupported signing algorithm: %v\", alg.Alg())\n\t}\n}\n\nfunc checkAclKeyLength(alg jwt.SigningMethod, key Sensitive) error {\n\tif !strings.HasPrefix(alg.Alg(), \"HS\") {\n\t\treturn nil\n\t}\n\n\tsl, err := strconv.Atoi(strings.TrimPrefix(alg.Alg(), \"HS\"))\n\tif err != nil {\n\t\treturn errors.Wrapf(err, \"error finding sha length for algo %v\", alg.Alg())\n\t}\n\n\t// SHA length has to be smaller or equal to the key length\n\tif sl > len(key)*8 {\n\t\treturn errors.Errorf(\"ACL key length [%v <= %v] bits for JWT algorithm [%v]\", len(key)*8, sl, alg.Alg())\n\t}\n\treturn nil\n}\n\nfunc RegisterAclAndEncFlags(flag *pflag.FlagSet) {\n\tregisterAclFlag(flag)\n\tregisterEncFlag(flag)\n\tregisterVaultFlag(flag, true, true)\n}\n\nfunc RegisterEncFlag(flag *pflag.FlagSet) {\n\tregisterEncFlag(flag)\n\tregisterVaultFlag(flag, false, true)\n}\n\nfunc registerAclFlag(flag *pflag.FlagSet) {\n\thelpText := z.NewSuperFlagHelp(AclDefaults).\n\t\tHead(\"ACL options\").","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/dgraph-io/dgraph/blob/759e242be62c91f8d084da06ad0c8d21256d9c07/x/acl_enc_keys.go#L124-L160","documentation":"For HS* algorithms, checkAclKeyLength requires the key to be at least as long as the SHA output: key length in bits (len(key)*8) must be >= the algorithm's SHA size. Otherwise it returns this error listing the actual and required bit lengths.","triggerScenarios":"GetEncAclKeys with an HS256/384/512 jwt-alg whose HMAC secret is shorter than 32/48/64 bytes respectively (e.g. a 10-byte password used as the secret for HS256).","commonSituations":"Operators choosing a short human-memorable secret; secrets truncated by config tooling; upgrading jwt-alg from HS256 to HS512 without lengthening the key.","solutions":["Provide a secret of at least 32 bytes for HS256, 48 for HS384, 64 for HS512 (openssl rand -hex 32)","Or downgrade jwt-alg to HS256 (or lower) to match the current key length","Avoid trailing newlines/encoding surprises by checking the actual file byte length","Store the generated secret in Vault/secret manager and reference it consistently"],"exampleFix":"// before\n--acl \"hmac-secret=short;jwt-alg=HS256\" # 5 bytes\n// after\nKEY=$(openssl rand -hex 32); --acl \"hmac-secret=$KEY;jwt-alg=HS256\" # 32 bytes","handlingStrategy":"validation","validationCode":"minBits := map[string]int{\"HS256\":256,\"HS384\":384,\"HS512\":512}\nif req, ok := minBits[algStr]; ok && len(secret)*8 < req {\n    return fmt.Errorf(\"secret too short: %d bits, need >= %d for %s\", len(secret)*8, req, algStr)\n}","typeGuard":null,"tryCatchPattern":"if _, err := x.GetEncAclKeys(flag, encKey); err != nil {\n    if strings.Contains(err.Error(), \"ACL key length\") {\n        log.Fatalf(\"lengthen the HMAC secret: openssl rand -hex 32 (HS256) / 48 (HS384) / 64 (HS512)\")\n    }\n    return err\n}","preventionTips":["Generate HMAC secrets with openssl rand -hex 32 or larger","Strip trailing newlines only after counting raw bytes","When upgrading HS256->HS512, regenerate/lengthen the secret","Store secrets in a manager that preserves exact bytes"],"tags":["jwt","acl","hmac","key-length"],"backgroundTag":"jwt-secret-too-short","analyzedSha":"759e242be62c91f8d084da06ad0c8d21256d9c07","analyzedAt":"2026-09-01T14:42:12.034Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}