Ollama Structured Outputs in 2026: JSON Schema, Pydantic, Zod & MLX Troubleshooting
Ollama structured outputs are useful when a local model needs to return data that another program can consume. The important distinction is between asking for JSON and actually enforcing a JSON schema. This guide explains a reliable workflow for JSON Schema, Pydantic and Zod, plus a current troubleshooting path for backend-specific failures.
JSON mode vs JSON Schema
| Method | Use | Validation |
|---|---|---|
| JSON mode | Simple machine-readable responses | Always parse and validate |
| JSON Schema | Known fields, types and constraints | Validate after parsing |
| Prompt-only JSON | Fallback | Strict validation is essential |
Ollama's official structured-output documentation supports both a JSON format and a JSON Schema passed through the format field. It also shows Pydantic and Zod examples. The safest application design is to use the same schema for generation and validation.
Test Ollama directly first
Before debugging LangChain, an agent framework or an application server, send a small request directly to Ollama. A minimal JSON Schema should contain only the fields you need.
curl http://localhost:11434/api/chat -H "Content-Type: application/json" -d '{"model":"gpt-oss","stream":false,"messages":[{"role":"user","content":"John is 25 and lives in Meerut. Extract his details."}],"format":{"type":"object","properties":{"name":{"type":"string"},"age":{"type":"integer"},"city":{"type":"string"}},"required":["name","age","city"]}}'Check the message content, parse it as JSON and validate it. An HTTP success response is not a substitute for application-level validation.
Python with Pydantic
from ollama import chat
from pydantic import BaseModel
class Person(BaseModel):
name: str
age: int
city: str
response = chat(
model="gpt-oss",
messages=[{"role": "user", "content": "John is 25 and lives in Meerut."}],
format=Person.model_json_schema(),
)
person = Person.model_validate_json(response.message.content)
print(person)This pattern is valuable because Pydantic becomes the final gate before the data reaches your database or business logic. If parsing or validation fails, handle it as an application error rather than silently accepting the response.
JavaScript with Zod
import ollama from "ollama";
import * as z from "zod";
const Person = z.object({
name: z.string(),
age: z.number().int(),
city: z.string()
});
const response = await ollama.chat({
model: "gpt-oss",
messages: [{ role: "user", content: "John is 25 and lives in Meerut." }],
format: z.toJSONSchema(Person)
});
const person = Person.parse(JSON.parse(response.message.content));Why backend testing matters in 2026
Recent Ollama GitHub issues show that structured output can expose backend-specific behavior. Reports in 2026 described MLX-backed models accepting the format request while returning unconstrained output, while corresponding GGUF variants enforced the schema. A later report described an MLX path that could keep producing whitespace until the output limit. These reports are specific to particular versions and models, so they should not be generalized to every MLX deployment. The practical lesson is to test the exact model, backend and Ollama version you plan to run.
Build a five-point verification test
- The request succeeds.
- The response content is valid JSON.
- The object passes your schema validator.
- Unexpected fields are rejected where appropriate.
- Generation terminates normally.
Use a deliberately restrictive test schema. For example, make an answer field an enum containing only yes and no. If the runtime returns prose, Markdown fences or unexpected values, do not put that response into production processing.
Thinking models need a separate check
Reasoning and structured output can interact differently across model and backend combinations. A September 2026 Ollama issue reported a stray character before JSON on an MLX thinking model, while disabling thinking removed the symptom. That issue was subsequently handled upstream, but it is a useful troubleshooting pattern: if extraction fails only with thinking enabled, test the same request with thinking disabled before changing the entire application.
"think": falseCommon failures and fixes
| Symptom | First check | Practical fix |
|---|---|---|
| Prose instead of JSON | Was format actually sent? | Test native Ollama API |
| Markdown code fences | Is schema enforcement active? | Use JSON Schema and validation |
| Missing required field | Schema and model support | Simplify schema, then add fields |
| Never-ending generation | Backend and done reason | Test another model/backend and lower output budget |
| Framework error before request | Client adapter | Reproduce with Ollama directly |
| GGUF works but MLX does not | Inference backend | Use the verified backend for critical workflows |
Keep schemas small
Start with the minimum object your application needs. Explicit types and required fields are easier to reason about than a huge schema with many optional branches. Add fields one at a time when testing a new model.
{"type":"object","properties":{"title":{"type":"string"},"score":{"type":"number"},"tags":{"type":"array","items":{"type":"string"}}},"required":["title","score","tags"]}Describe the schema in the prompt too
Ollama recommends grounding the model by also describing the expected structure in the prompt. This gives the model semantic context while the format parameter handles output constraints. It is not a replacement for validation.
For extraction, say what to do when information is absent and explicitly tell the model not to invent values. For example: “Return the requested fields. If a value is not present in the supplied text, return null. Do not infer missing identifiers.”
Use low temperature for extraction
Ollama's documentation recommends lowering temperature for more deterministic structured output. Temperature 0 is a sensible starting point for extraction workloads when supported by the model.
"options": {"temperature": 0}Deterministic generation does not prove that the extracted fact is true. Business rules and source verification remain your application's responsibility.
Structured outputs for RAG
Structured output is useful after retrieval. A RAG application can request an answer, retrieved source IDs and an unanswered flag. After validation, the application should confirm that every source ID belongs to the actual retrieval result. Otherwise a model can produce syntactically valid but invented references.
This complements GyanAangan's existing local RAG architecture guidance: retrieval supplies evidence, the model produces a structured answer, and application validation controls what reaches the next stage.
Privacy and security
- Keep Ollama on localhost unless remote access is required.
- Do not log credentials or sensitive prompts unnecessarily.
- Validate model output before writing to a database or invoking tools.
- Pin model and runtime versions for workflows where output shape matters.
- Do not assume local inference means every component is local; frameworks, MCP servers and external APIs can still transmit data.
When structured output is not enough
JSON Schema validates shape, not truth. A model can return a perfectly valid object containing an incorrect date, amount or classification. For high-impact workflows, validate important fields against authoritative data after parsing.
If a backend cannot reliably enforce the schema you require, use a verified model/backend, simplify the schema, disable a problematic reasoning mode or use prompt-based JSON with strict post-validation as a fallback. Do not rely on unlimited retries to compensate for a runtime capability problem.
FAQ
Does Ollama guarantee valid JSON?
Structured outputs are designed to constrain generation, but production applications should still parse and validate every response.
Why does a model return Markdown?
Check that the format field was sent, the schema is valid and the selected backend supports the feature. Test directly against Ollama before debugging a higher-level framework.
Why can GGUF work while MLX fails?
Different Ollama model variants can use different inference engines. Current GitHub reports show backend-specific structured-output behavior, so test the exact variant you deploy.
Should I use Pydantic or Zod?
Use whichever matches your application language. Both provide a strong final validation layer after generation.
Should I use JSON mode or JSON Schema?
Use JSON mode for simple machine-readable responses and JSON Schema when your application depends on specific fields and types.
Official sources
- Ollama Structured Outputs documentation
- Ollama GitHub repository
- Ollama MLX structured-output issue
- Ollama MLX structured-output termination issue