llama.cpp 报错 “System message must be at the beginning”:3 种实测解法(2026)
“System message must be at the beginning” 是模型聊天模板拒绝了请求:system 消息不在第一条,或有两条。实测三种解法:合并成一条放最前面、用 --chat-template chatml 启动、改一份模板副本。

先说结论:这个报错不是 llama.cpp 引擎的问题,而是模型文件里自带的聊天模板(chat template)在拒绝你的请求。模板规定“system 消息只能放在第一条”,而你的客户端把它放在了别处,或者发了两条。最干净的办法是在客户端把所有 system 内容合并成第 0 位的一条 system 消息。改不了客户端的话,就用更宽松的模板启动服务,比如 --chat-template chatml。我在 llama.cpp 构建 11963 上复现了这个报错,下面三种解法都实测过。
“System message must be at the beginning”是什么意思
llama-server 返回的完整报错长这样(中间我省略了一段):
{"error":{"code":400,"message":"Unable to generate parser for this template. Automatic parser generation failed: ... Error: Jinja Exception: System message must be at the beginning.","type":"invalid_request_error"}}
新版 llama-server 会读取 GGUF 文件里存的 Jinja 聊天模板,每个请求都跑一遍(按 llama.cpp server README,--jinja 默认开启)。有些模板里写了一道检查。比如 Hugging Face 上 Qwen/Qwen3.5-35B-A3B 的 chat_template.jinja 就有这一行:raise_exception('System message must be at the beginning.')。检查触发时,llama.cpp 返回 HTTP 400 和上面那段话。
所以有三件事同时成立:模型权重没坏,内存也没问题,是请求被模板拒绝了。
我是怎么复现的(实测)
我没有跑 Qwen3.5 本体。为了测试够小,我用了 Hugging Face 上 ggml-org 仓库里 1.19 MB 的测试模型 stories260K.gguf,再给服务器一个带同样检查的模板文件(system 不在第一条就 raise_exception)。服务器是 Linux 上的 llama.cpp 构建 11963,纯 CPU:
llama-server -m stories260K.gguf --jinja --chat-template-file tpl.jinja --port 18091 -c 512
然后往 /v1/chat/completions 发了四种请求:
| 发送的消息顺序 | 结果 |
|---|---|
| user,然后 system | HTTP 400,“System message must be at the beginning.” |
| system、system、user | HTTP 400,同样的报错(第二条 system 不是第一条) |
| system、user、assistant、system、user | HTTP 400,同样的报错 |
| 合并成一条 system,然后 user | 正常,模型有回答 |
第二行最容易让人意外:不用有“晚到”的消息,连续两条 system 就够触发。
你也可以看服务器加载了哪个模板:curl localhost:8080/props 会返回 chat_template 字段,里面就是模板文本(我在构建 11963 上确认了这个字段存在)。
解法一:只发一条 system,放在最前面(改客户端)
这是最干净的办法。把所有指令合并成一条消息,放第一位:
{"messages":[
{"role":"system","content":"规则 A。\n\n规则 B。"},
{"role":"user","content":"hi"}
]}
我的测试里这个请求通过了。如果某个工具或插件会在对话中途加一条“system 提醒”,去找有没有“合并 system 提示词”的设置,或者关掉这个功能。具体有没有这个设置取决于客户端,请看它自己的文档。
解法二:用不做检查的模板启动服务
改不了客户端,就换掉模型自带的模板。llama.cpp README 列出了内置模板,chatml 就是其中之一。README 的工具调用部分也把 --chat-template chatml 列为“最坏情况下可能有效”的选项,所以这是已知的退路:
llama-server -m model.gguf --jinja --chat-template chatml
我的测试里,同样的“坏请求”(先 user 后 system)在内置 chatml 模板下得到了正常回答。两点提醒:
- 内置模板不一定和模型训练时的格式一致,回答质量可能略差,请用自己的提示词试一下。
- 如果你要用工具调用,README 说可能需要支持工具的
--chat-template-file,这时别盲目换模板。
解法三:改一份模型自带模板的副本
从模型的 Hugging Face 页面下载 chat_template.jinja,删掉或放宽 raise_exception('System message must be at the beginning.') 这个分支,再加载:
llama-server -m model.gguf --jinja --chat-template-file my-template.jinja
这样保留了模型自己的格式,但位置奇怪的消息可能被渲染到模型没见过的位置。把它当作临时办法,并留好原文件方便对照。
它不是什么
- 不是内存不足。内存问题请看 Ollama model requires more system memory 怎么办。
- 不是启动时的 “–model or -hf is required”。那个在 llama.cpp “error: –model or -hf is required” 里讲了。
- 不是 GGUF 文件坏了。另一个报错 “unknown model architecture” 在 Ollama unknown model architecture 里。
更多 llama.cpp 和 Ollama 报错汇总在 Ollama 与 llama.cpp 报错清单。还在选模型的话,看 本地大模型推荐。
常见问题
这个报错是不是说明我的模型文件坏了?
不是。文件加载成功,服务也启动了,只是请求被模板的检查拒绝。
为什么有的模型会出现,有的不会?
只有部分模板写了这道检查。Qwen3.5 的模板有;我查的 Qwen3-8B 的 tokenizer 配置里没找到这句话,其他模型我没有逐个查。
--no-jinja 能解决吗?
我没有测。README 说 --jinja 默认开启,而且工具调用需要它,所以关掉它不适合作为第一步。先合并 system 消息。
--chat-template 和 --chat-template-file 有什么区别?
前者接收模板名称或模板文本,后者接收文件路径。两者都会替换模型里存的模板。
来源与测试说明
- llama.cpp server README(选项、内置模板、工具调用说明):github.com/ggml-org/llama.cpp 的
tools/server/README.md。 - Hugging Face 上 Qwen3.5-35B-A3B 的
chat_template.jinja(包含这句报错原文)。 - 自己实测:llama.cpp 构建 11963,Linux 纯 CPU,
stories260K.gguf加我自己写的带检查的模板。没测:真正的 Qwen3.5 权重、工具调用、--no-jinja。