Claude Structured Outputs on Amazon Bedrock - Where the Schema Goes, What the Grammar Cache Keeps, and Why stop_reason Comes First
First Published:
Last Updated:
bedrock-mantle endpoint. The grammar associated with constrained decoding ensures the validity of the output's structure. When a new schema is received, Amazon Bedrock compiles the grammar and caches the compiled grammar.This article details where to define the schema, which schemas are rejected and when, what the grammar cache retains, and what the caller receives when the output does not conform to the schema. It presents this information in tables, outlining entry points and providing a breakdown of rejected schemas and the timing of those rejections. There are two ways to count the locations where you can define the schema (based on request format) and four when counting by entry point. Schema rejections can result in immediate responses at the time of the request, or, during grammar compilation, can take up to approximately 90 seconds. In two specific scenarios where the output does not conform to the schema (
max_tokens and model refusals), an error is not returned; instead, a response is provided. Therefore, the caller must check the stop reason before parsing the JSON.This article is neither an introduction to structured outputs functionality nor a primer on JSON Schema. It does not cover methods for validating the accuracy of the output's content, nor does it discuss pricing. The information presented was verified as of October 30, 2026. On the same day, 28 calls were observed in a demo setup.
Related articles on this site:
- LLM API Parameter Compatibility Reference - Anthropic, OpenAI, Google Gemini, and Amazon Bedrock
- LLM Output Verification Patterns - Grounding Checks, Self-Verification, Cross-Model Review, and Citation Enforcement
- Amazon Bedrock Converse API Deep Dive - Unified Model Interface, Conversation State, Tool Use, and Streaming
- Amazon Bedrock Inference Endpoints and API Keys - What bedrock-runtime and bedrock-mantle Each Accept, Which IAM Action Each Call Checks, and What CloudTrail Records
- Anthropic Claude API Errors Reference - HTTP Status Codes, Error Types, Causes, and Official Solutions
- Amazon Bedrock Errors and Exceptions Reference - Runtime Exceptions, Causes, and Official Solutions
Table of Contents
- 1. Scope and Assumptions
- 2. How to Read the Tables
- 3. Schema Location - Two Request Shapes, Four Entry Points
- 4. Rejected Schemas and Time Until Rejection
- 5. Grammar Compilation and Caching
- 6. Two Cases Outside the Guarantee, and Why to Check the Stop Reason First
- 7. Key Differences When Choosing an Entry Point
- 8. What This Setup Showed
- 9. Discrepancies, Omissions, and Changes in the Documents
- 10. Failure Modes
- 11. Frequently Asked Questions About Claude Structured Outputs on Amazon Bedrock
- 12. Summary
- 13. References
1. Scope and Assumptions
This section will first define the intended audience, the scope of this article, the source materials consulted, and how to distinguish between different entities that may share the same name. The following nine points will outline the conclusions.- The place where the schema is written splits into two by request shape. Shape A is the Anthropic-native request body and writes the schema as a JSON object in the
output_config.formatfield. This applies to InvokeModel, InvokeModelWithResponseStream, the Messages API inbedrock-runtime, and the Messages API inbedrock-mantle. Shape B is the Converse request body and writes the schema as a JSON string in theoutputConfig.textFormat.structure.jsonSchema.schemafield. This applies to Converse and ConverseStream. - The available entry points vary depending on the model. According to the model cards, Claude Opus 4.5, Claude Opus 4.6, Claude Sonnet 4.5, and Claude Sonnet 4.6 only support Converse and InvokeModel within
bedrock-runtime. Claude Opus 4.7 and later Opus models, Claude Sonnet 5 and later Sonnet models, Claude Haiku 4.5 and Claude Haiku 5.5, and Claude Fable 5 and Claude Fable 5.1, all support the Messages API in bothbedrock-runtimeandbedrock-mantle(the Regions are in a separate table on each card; see Section 3.5). - According to the user guide, unsupported JSON Schema features, a missing
additionalProperties, an invalidpattern, or more than 16 union-typed properties return a 400 immediately at request time. However, in this article's demo setup,minLength, which is listed as unsupported, did not return a 400. More than 12 optional properties are rejected during grammar compilation, and according to the user guide the error can take up to approximately 90 seconds to return. In this article's demo setup, it returned after approximately 45 seconds. - The initial request for a new schema may take up to approximately 90 seconds for grammar compilation. The user guide recommends setting the client's read timeout to 120 seconds or more. Once compiled, the grammar is cached for 24 hours from first access and can be reused with the same schema for the same account.
- If
max_tokensstops generation, even with structured output enabled, the JSON output is truncated. In this setup, all four APIs – InvokeModel, Converse, ConverseStream, and the Messages API inbedrock-mantle– returned a truncated JSON within an HTTP 200 response. - Model refusals (indicated by
refusal) are documented as a Shape A stop reason value on the Messages API page of the Amazon Bedrock user guide. The Anthropic documentation states that the refusal output may not conform to the schema, and the status code will be 200. - Shape B's Converse does not list
refusalin thestopReasonenumeration. However, an AWS ML Blog from February 2026 says to check for refusals usingstopReason. No statement was found on which value a Claude refusal returns in Converse. - An announcement from October 20, 2026, refers to all Claude models. The user guide clarifies that support varies depending on the model and endpoint. The model cards do not list structured output for Legacy Claude Opus 4.1 and the discontinued Claude Sonnet 4.
- Different sources, AWS documentation and Anthropic documentation, use different numerical values for the same features. These discrepancies include the maximum number of optional properties, the start time for the cache expiration, and the compilation time. This article writes Amazon Bedrock values with sentences from AWS documents and lists Anthropic values as sentences from Anthropic's pages.
1.1 Intended Audience
This article is intended for developers who are either currently integrating JSON output into applications that call Claude on Amazon Bedrock, or who are planning to do so. Specifically, this article targets readers who believe any of the following statements to be true:- Enabling structured output will guarantee that only JSON conforming to the schema is returned.
- The same schema format can be used regardless of whether you use the InvokeModel or Converse method.
- Structured outputs work on all Claude models and all entry points.
- If there is a problem with the schema, errors will be returned immediately.
- When the output does not conform to the schema, it can be reliably detected as an error.
However, it is important to understand that the validity of each of these assumptions depends on factors such as which entry point and model you are using, what you have defined in your schema, and which stop reason the response ended with.
1.2 What This Article Covers and What It Does Not
This article will address the following topics:- The location and data types of schemas for each entry point, as well as how to write strict tools and the names of the stop reason fields.
- Rejected schemas and the time it takes to receive a rejection response.
- Grammar compilation and caching.
- The two scenarios where the output does not match the schema, and what the caller receives in those cases.
- Key differences that apply when selecting an entry point (Guardrails, citations, mapping models to endpoints).
- Areas where the documentation is inconsistent, silent, or has changed over time.
This article does not cover the following topics. It also does not cover pricing.
- A comparison table of structured output parameters for Anthropic, OpenAI, Google Gemini, and Amazon Bedrock. Covered in the existing LLM API Parameter Compatibility Reference.
- Methods for verifying the accuracy of output, and the fact that shape validation does not guarantee meaning. Covered in the existing LLM Output Verification Patterns.
- A comprehensive overview of the Converse API (conversation state, tools, streaming). Covered in the existing Amazon Bedrock Converse API Deep Dive.
- The differences between
bedrock-runtimeandbedrock-mantle, along with information on authentication, IAM, and CloudTrail. Covered in the existing Amazon Bedrock Inference Endpoints and API Keys. - A list of HTTP status codes and error types for the Claude API. Covered in the existing Anthropic Claude API Errors Reference.
- A list of runtime exceptions for Amazon Bedrock. Covered in the existing Amazon Bedrock Errors and Exceptions Reference.
- What
max_tokenscounts. Covered in the existing Controlling How Much a Model Thinks. - Detailed information on structured output for models other than Claude (OpenAI's GPT, open-weight models, and Amazon Nova).
- How to use structured output with the Claude API (the API directly provided by Anthropic). This article cites Anthropic's pages only when it lines up differences between the sources.
- Examples of requests that trigger model refusals. The demonstrations in this article do not trigger model refusals.
- Determining when to route requests to an alternative destination is covered in the related article, Model Fallback in Amazon Bedrock AgentCore Gateway.
- The article on Where a Web Search Domain Filter Is Enforced covers where to define the scope of web searches.
1.3 Verification Date and Reviewed Materials
The information was verified on October 30, 2026. The materials reviewed are as follows. In this document, the names of these materials will be abbreviated as follows.- Amazon Bedrock User Guide (hereinafter referred to as UG): The Get validated JSON results from models page (hereinafter referred to as the UG's Structured Output page), the page for Structured outputs for Anthropic Claude models (hereinafter referred to as the UG's Claude page), the page for Inference endpoints supported by Amazon Bedrock (hereinafter referred to as the UG's Endpoint page), the page for Anthropic Claude Messages API Request and Response (hereinafter referred to as the UG's Messages page), the page for Fallback credit for refused requests (beta), the Use a guardrail with the Converse API page, and Anthropic's 19 model cards.
- Amazon Bedrock API Reference (hereinafter referred to as API Reference):
Converse,ConverseStream,MessageStopEvent,OutputConfig,OutputFormat,OutputFormatStructure,JsonSchemaDefinition,ToolSpecification. - What's New announcements: Structured outputs now available in Amazon Bedrock (February 4, 2026), Amazon Bedrock now supports structured outputs to AWS GovCloud (US) Regions (April 1, 2026), Structured outputs for Claude models available on Amazon Bedrock (October 20, 2026).
- AWS Machine Learning Blog: Structured outputs on Amazon Bedrock: Schema-compliant AI responses (February 6, 2026, hereinafter referred to as the ML Blog's February article), Structured outputs for Anthropic Claude models on Amazon Bedrock (October 19, 2026, hereinafter referred to as the ML Blog's October article).
- Claude Platform Docs (Anthropic documentation): The page for Structured outputs (hereinafter referred to as Anthropic's Structured Output page), the page for Stop reasons and fallback, the page for Claude in Amazon Bedrock (Opus 4.7 and later), and Release notes.
- Archived versions of the UG's Endpoint page (October 6, 2026) and the UG's Claude page (July 2, 2026) from the Internet Archive's Wayback Machine.
- Amazon Bedrock Runtime service model in the AWS SDK for Python (botocore) (version 1.43.121).
This article references specific sentences from various sources. The same subject matter is addressed on the two UG pages, on the ML Blog, and on an Anthropic page, but each source uses different sentences to describe it, resulting in variations in the scope of information presented on each page.
1.4 Similar Spellings, Different Meanings
In this article, similar terms are distinguished as follows:- Structured outputs: This term refers to a combined functionality encompassing both JSON output (JSON Schema output format) and strict tool usage. JSON output aligns the response body with a schema, while strict tool usage aligns the tool's name and input with the schema. It is distinct from JSON mode, which only requires the system to return valid JSON without guaranteeing schema compliance.
- Grammar: In this article, "grammar" refers to the artifact compiled from a schema by Amazon Bedrock for constrained decoding. It is distinct from the grammar of natural or programming languages.
- Grammar Caching and Prompt Caching: Grammar caching is the mechanism by which Amazon Bedrock stores the compiled grammar; no request field for configuring it was found in the API references. Prompt caching is a mechanism that reuses the computed results of the initial portion of a prompt, using checkpoints set by the caller. The two are distinct.
- Stop Reasons: Shape A responses include the field
stop_reason, while Shape B (Converse) responses includestopReason. The lists of possible values are also different; Shape B's list does not includerefusal. Shape A responses also includestop_detailswhen a refusal occurs. - Schema Rejection and Model Refusal: Schema rejection occurs when Amazon Bedrock does not accept the schema, returning a 400
ValidationException. Model refusal occurs when the model declines to respond for safety reasons, returning a response with arefusalstop reason. This article uses different terminology to refer to these two concepts. max_tokensandmaxTokens: Both represent the maximum number of tokens in the output. In Shape A, it ismax_tokens, while in Shape B (Converse), it ismaxTokensin theinferenceConfig. The value ofmax_tokensin the stop reason is the same in both shapes.
1.5 Entry Points
Amazon Bedrock's inference endpoints consist of two options:bedrock-runtime and bedrock-mantle. The UG's Endpoint page recommends bedrock-runtime for new applications.For most new applications, use the bedrock-runtime endpoint.
The API table on the same page shows that
bedrock-runtime offers APIs for InvokeModel, Converse, Chat Completions, Responses, and Messages, while bedrock-mantle offers APIs for Responses, Chat Completions, and Messages. However, the API table in the Claude model card indicates that only Messages, Converse, and InvokeModel are supported with Claude, with no indication of support for Responses or Chat Completions across any Claude model card. The UG's Claude page also describes the entry points as follows:On bedrock-runtime, you can use the Converse API, the InvokeModel API, or the Anthropic Messages API.
On bedrock-mantle, you use the Anthropic Messages API.
This article refers to these four (InvokeModel, Converse, the Messages API for
bedrock-runtime, and the Messages API for bedrock-mantle) as entry points. InvokeModelWithResponseStream and ConverseStream are included in the same entry points as the streaming versions of InvokeModel and Converse.2. How to Read the Tables
This section defines the columns in the tables from Sections 3 through 9, as well as how to describe the status of the materials. The terminology used for the columns and status descriptions is consistent across three articles in the same series. This article adds how to tell AWS documentation from Anthropic documentation, and HTTP status from stop reason.2.1 Columns
The tables in this article are structured with aLayer column at the beginning, followed by subsequent columns. In some tables, the Layer column may be replaced with a column indicating the entry point or schema type.What It Decides: What this layer determines.What the Caller Receives: What the caller receives as a result of this layer's decision.Where It Is Written: The source of the statement in this row. This indicates the document and page.No Statement Found: Instances where, after searching the materials described in Section 1.3, using different search terms and document categories, no relevant statement was found. When there is nothing to list, it is marked with—.
A non-empty
No Statement Found entry does not necessarily indicate that the described situation does not exist or will not occur.2.2 Four States
The condition of the information is described using the following four terms:- No statement was found: In the text, this is written as
no statement was found, accompanied by the scope of the search. - The documentation does not list: This indicates that the item is not included in a list or table. In the text, this is written as
the documentation does not list. - The sources disagree: In the text, this is written as
the sources disagree, and both statements, along with their sources, are presented. This article does not definitively identify either source as incorrect. - Inference: In the text, this refers to this article's reading, and is not a statement found in any of the source materials. This is indicated in the same sentence.
2.3 Layer Terms
This article refers to layers using the following four terms:- Caller: The application that invokes Amazon Bedrock, including its SDK.
- Entry point: The API and endpoint combination through which the caller submits requests.
- Validation and grammar: The stage where Amazon Bedrock validates the schema, compiles the grammar, and caches it.
- Model: The component that generates output in the constraints of the grammar and returns a response with a stop reason.
2.4 AWS Documentation and Anthropic Documentation
The same functionality is described in both AWS documentation and Anthropic documentation. This article will differentiate between the two sources according to the following rules:- Values related to Amazon Bedrock will be written using text from AWS documentation (User Guide, API Reference, Model Cards, What's New, ML Blog).
- Values from Anthropic's pages will be clearly identified as originating from Anthropic's documentation in the same sentence. They will not be presented as Amazon Bedrock values.
- When the values differ, both versions of the text, along with their respective sources, will be presented in Section 9.
2.5 Statements of Benefits and Statements of Limitations
The documentation contains statements describing the benefits of a feature, as well as statements outlining its limitations. For example, the UG's Claude page states that all responses will be valid JSON, while the UG's Structured Output page notes that JSON output is truncated by themax_tokens setting. As the specification, this article quotes the statements of limitations; the statements of benefits are set beside them in Section 9.7.2.6 HTTP Status and Stop Reason
This article describes what the caller receives, dividing it into HTTP status codes and stop reason. Schema rejections return an HTTP 400 error, and no output is provided. In cases where the output does not conform to the schema, an HTTP 200 response is returned, with the stop reason indicating the issue. An HTTP status of 200 does not necessarily mean that the output conforms to the schema.3. Schema Location - Two Request Shapes, Four Entry Points
This section shows, for each entry point, which field the schema goes in and with what type. In conclusion, there are five key points:- For Shape A (Anthropic-native request body), write
typeandschemainoutput_config.format, whereschemais a JSON object. - For Shape B (Converse request body), write
typeandstructureinoutputConfig.textFormat, wherestructure.jsonSchema.schemais a JSON string. - For strict tools, in Shape A, this is specified within each element of
toolsasstrict. In Shape B, it is specified within each element oftoolConfig.toolsastoolSpec.strict. - The field for specifying the stop reason is
stop_reasonin Shape A andstopReasonin Shape B. - The API table in the model card determines which entry points are available.
3.1 Shape A - Anthropic-Native Request Body
The UG's Structured Output page describes the fields for InvokeModel and Converse as follows:For InvokeModel API with Anthropic Claude models, use the output_config.format request field.
With open weight models, use the response_format request field.
For Converse APIs, use the outputConfig.textFormat request field.
The UG's Claude page states that the InvokeModel body is Anthropic-native and gives the schema type as follows:
With the InvokeModel API, you send the Anthropic-native request body, so the schema goes in
output_config.format as a JSON object (not a JSON string).
A Shape A body looks like this. In the InvokeModel body, include
anthropic_version with the value bedrock-2023-05-31.{
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 512,
"messages": [{"role": "user", "content": "Extract the fields from this ticket: ..."}],
"output_config": {
"format": {
"type": "json_schema",
"schema": {
"type": "object",
"properties": {
"category": {"type": "string", "enum": ["billing", "technical", "account", "other"]},
"summary": {"type": "string"}
},
"required": ["category", "summary"],
"additionalProperties": false
}
}
}
}
The Messages API is available in both
bedrock-runtime and bedrock-mantle. The UG's Endpoint page states that output_config.format is supported on both endpoints.The Messages API is available on both endpoints. Structured outputs (the output_config.format
parameter) is supported for Anthropic Claude models on both the bedrock-runtime and bedrock-mantle
endpoints.
The URL for the Messages API in
bedrock-mantle is https://bedrock-mantle.{region}.api.aws/anthropic/v1/messages. In the Anthropic SDK, the AnthropicBedrockMantle client calls this endpoint. The request body is Shape A. The wording of this UG note previously stated the opposite; this will be addressed in Section 9.8.3.2 Shape B - Converse Request Body
The Converse fields are nested across four data types in the API reference. TheOutputConfig page says these fields belong to Converse and ConverseStream.Output configuration for a model response in a call to Converse or ConverseStream.
OutputConfig includes a textFormat field, which is of type OutputFormat. OutputFormat includes type and structure fields. The valid values for type are only json_schema. structure is a union of type OutputFormatStructure, and includes jsonSchema. jsonSchema is of type JsonSchemaDefinition and includes schema, name, and description. On the JsonSchemaDefinition page, schema is a required string field, while name and description are optional properties.In Shape B, the schema is converted to a JSON string and placed in the
schema field. In boto3, this is written as follows.import json
import boto3
runtime = boto3.client("bedrock-runtime", region_name="us-east-1")
schema = {
"type": "object",
"properties": {
"category": {"type": "string", "enum": ["billing", "technical", "account", "other"]},
"summary": {"type": "string"},
},
"required": ["category", "summary"],
"additionalProperties": False,
}
response = runtime.converse(
modelId="us.anthropic.claude-haiku-5-5",
messages=[{"role": "user", "content": [{"text": "Extract the fields from this ticket: ..."}]}],
inferenceConfig={"maxTokens": 512},
outputConfig={
"textFormat": {
"type": "json_schema",
"structure": {
"jsonSchema": {
# The schema is a JSON string here, not an object.
"schema": json.dumps(schema),
"name": "ticket_fields",
"description": "Fields extracted from a support ticket",
}
},
}
},
)
print(response["stopReason"])
It is not possible to directly insert the schema object from Shape A into the
schema field in Shape B. This is because the API reference uses string types. Conversely, in Shape A, as the UG's Claude page states, the schema is written as an object rather than a string. The ML Blog's October article states that the schema counts toward the Converse API payload size.Basic schemas compile faster, are easier to debug, and keep your request payload lean because the
schema counts toward the Converse API payload size.
The
name and description fields in Shape B are not present in Shape A. The ML Blog's February and October articles say that changing only name or description fields does not invalidate the cache; as Section 5.3 explains, the articles do not say whether those are these two Shape B fields.3.3 Strict Tools
A strict tool addsstrict to the tool definition. The UG's Claude page states:Add strict: true to a tool definition to validate tool names and inputs against the schema.
You can use these mechanisms independently or together.
In Shape A,
strict and input_schema are included for each element in the tools array. In Shape B, strict is added to the toolSpec of each element within toolConfig.tools, and the schema is defined in inputSchema.json. The API reference page for ToolSpecification describes strict as follows:Flag to enable structured output enforcement on a tool usage response.
Anthropic's Structured Output page clarifies that the grammar for JSON output applies only to the model's direct output. Making tool call inputs conform to the schema is the job of strict tools.
Grammars apply only to Claude’s direct output, not to tool use calls, tool results, or thinking tags
Anthropic's Structured Output page also states that a single request can use up to 20 strict tools. No statement on a limit on the number of strict tools was found in the Amazon Bedrock documentation. This is a
no statement was found state; the search covered the two UG pages, the API reference for ToolSpecification, and the two ML Blog articles.3.4 Streaming
The table on the UG's Structured Output page indicates that both Converse and ConverseStream, as well as InvokeModel and InvokeModelWithResponseStream, support structured output. The stop reason arrives at the end of the stream. In a Converse stream, it is themessageStop event's stopReason; in a stream formatted as Messages, it is the stop_reason in the final message_delta. The API reference page for MessageStopEvent lists stopReason as a required field.No statement was found specifying how much of the JSON is completed at any given point during the stream. Given that the stop reason is delivered at the end, this article reads that parsing the entire JSON object occurs only after the stream has concluded.
3.5 Entry Points Available for Each Model
Which entry points are available depends on the model, as specified in the 'Endpoints and APIs supported' table on each model card. This article groups the 19 Anthropic model cards, as of October 30, 2026, into the following four categories:bedrock-runtime(Messages, Converse, InvokeModel) andbedrock-mantle(Messages): Claude Fable 5.1, Claude Fable 5, Claude Opus 5.5, Claude Opus 5, Claude Opus 4.8, Claude Opus 4.7, Claude Sonnet 5.5, Claude Sonnet 5, Claude Haiku 5.5, Claude Haiku 4.5.bedrock-runtime(Converse and InvokeModel) only: Claude Opus 4.6, Claude Opus 4.5, Claude Sonnet 4.6, Claude Sonnet 4.5, Claude Opus 4.1, Claude Sonnet 4, Claude 3 Haiku.bedrock-mantle(Messages) only: Claude Mythos 5.bedrock-runtime(Messages, Converse, InvokeModel) only: Claude Mythos 5.1.
This grouping is by endpoint and API, not by Region. Even for the same model, the available endpoints may vary by Region. For example, the Claude Haiku 5.5 card lists only us-gov-west-1 as a Region where
bedrock-mantle is supported. As described in Section 8.6, in this article's setup, attempting to specify Claude Haiku 5.5 with bedrock-mantle in the us-east-1 Region resulted in a 404 error, indicating that the model was not found.3.6 Deprecation of output_format
The UG's Structured Output page states that the output_format field is deprecated.The output_format field is deprecated. Use output_config.format instead.
The
output_format= argument received by Anthropic's Python SDK's client.messages.parse() is an argument of the SDK helper, not a field of the request body. Anthropic's Structured Output page explains that this helper function transforms Pydantic model schemas and sends them as output_config.format.3.7 Table by Entry Point
| Entry Point | Schema Field | Schema Value | Strict Tool Field | Stop Reason Field | Where It Is Written | No Statement Found |
|---|---|---|---|---|---|---|
InvokeModel and InvokeModelWithResponseStream (bedrock-runtime) | output_config.format.schema | JSON object | tools[].strict | stop_reason | UG's Structured Output page, UG's Claude page | — |
Messages API (bedrock-runtime) | output_config.format.schema | JSON object | tools[].strict | stop_reason | UG's Endpoint page, UG's Claude page | Example request for structured output from this entry point |
Messages API (bedrock-mantle) | output_config.format.schema | JSON object | tools[].strict | stop_reason | UG's Endpoint page, UG's Claude page | — |
Converse and ConverseStream (bedrock-runtime) | outputConfig.textFormat.structure.jsonSchema.schema | JSON string | toolConfig.tools[].toolSpec.strict | stopReason | API Reference for OutputConfig, JsonSchemaDefinition, ToolSpecification | Value of stopReason for a Claude refusal |

4. Rejected Schemas and Time Until Rejection
This section shows which schemas Amazon Bedrock rejects and when the rejection returns. In conclusion, there are five key points:- According to the UG, unsupported JSON Schema features return a 400 immediately at request time. However, in this article's setup,
minLengthdid not return a 400. objecttypes that do not specifyadditionalPropertiesasfalse, as well as invalidpatternspecifications, result in a 400ValidationException.- If a schema has more than 16 union-typed properties, it immediately results in a
ValidationException. - If a schema has more than 12 optional properties, a
ValidationExceptionoccurs during grammar compilation, and according to the UG it can take up to approximately 90 seconds to return. - The
defaultkeyword is accepted, but not enforced.
4.1 Immediate Rejection Upon Request
The Request workflow section of the UG's Structured Output page states the following regarding schemas with unsupported features:Schema validation – Amazon Bedrock validates the JSON schema format against the supported JSON Schema
Draft 2020-12 subset. If the schema contains unsupported features, Amazon Bedrock returns a 400 error
immediately.
The same page lists five unsupported features: recursive schemas, external
$ref references, numerical constraints (minimum, maximum, multipleOf), string constraints (minLength, maxLength), and additionalProperties that are not set to false.Regarding
additionalProperties, the same page states:When you use structured outputs, every object in your schema must explicitly set additionalProperties
to false. If an object omits additionalProperties, or sets it to any value other than false, Amazon
Bedrock returns a 400 ValidationException.
The
pattern regular expression supports only a subset of features, excluding lookarounds and backreferences. Invalid regular expressions will result in a ValidationException (400).An invalid or unsupported regular expression returns a 400 ValidationException with the message
"Invalid regex in pattern field."
Items with a union type, defined either by an array of
type values or using the anyOf keyword, are limited to a maximum of 16.Union-typed properties. A schema can contain a maximum of 16 properties that use a type array (for
example, "type": ["string", "null"]) or anyOf. A schema that exceeds this limit returns a
ValidationException immediately.
In this article's setup, the absence of
additionalProperties, pattern expressions containing lookarounds, 17 union-typed properties, and the use of citations all resulted in a 400 error in about 0.5 seconds. Conversely, schemas containing minLength (a feature that UG identifies as unsupported) did not return a 400 error, but instead returned a 200 response. This is discussed further in Section 8.3.4.2 Rejection During Grammar Compilation
The maximum number of optional properties is 12 across the entire schema. The Limits section of the UG's Structured Output page states the following:Optional properties. A schema can contain a maximum of 12 optional properties in total, counted across
all nested objects in the schema. An optional property is any property that is not listed in required,
including an optional object-valued property. A schema that exceeds this limit returns a
ValidationException with the message "Schema is too complex." Amazon Bedrock enforces this limit while
it compiles the grammar, so the error can take up to approximately 90 seconds to return.
Optional properties are counted, including those within nested
object structures, and are not listed in the required section. This rejection occurs during grammar compilation, rather than at the time of the request. Consequently, the caller will need to wait to receive the rejection notification. In the configuration described in this article, schemas with 13 optional properties resulted in a ValidationException with the message Schema is too complex. approximately 45 seconds after the request, on both InvokeModel and Converse. Schemas with exactly 12 optional properties were accepted, although the initial request took approximately 53 seconds.The waiting time for this rejection is also related to the client read timeout described in Section 5.1. This article reads that if the timeout is short, the caller may terminate the request due to its own timeout before receiving the
ValidationException.4.3 default Is Not Enforced
The UG's Structured Output page describes the default keyword as follows:The default keyword is accepted but is not enforced. Constrained decoding does not insert the default
value. The model uses it only as a hint when it generates a value, so the value is not guaranteed. A
property that specifies a default remains optional unless you list it in required, so it counts toward
the limit of 12 optional properties described in Limits.
A property with
default stays optional unless it is listed in required, and it counts toward the limit of 12. In this article's setup, for an inquiry whose text does not mention a currency, an optional property with USD as its default contained USD in both of two requests. These two observations cannot show either that the value is not enforced or that it is enforced. The UG text states that the system does not guarantee the value.4.4 How to Write More Than 12 Fields, and the Limit
The UG's Structured Output page explains how to write more than 12 fields that might be absent, as follows:To include more than 12 fields that might be absent, list the fields in required and make each one
nullable by using a type array, such as "type": ["string", "null"]. The model returns null for any
field that it cannot fill. Because nullable fields are union-typed, you can define a maximum of 16 of
them.
Properties that can be
null are union-typed properties, and are counted towards the limit of 16. The limit for union types is the total number of properties defined using the type array and properties defined using anyOf. Therefore, this article reads that properties that allow null and other anyOf properties share the same limit of 16. In this article's setup, a schema with 14 required properties that allow null is accepted, and in the recorded data, null values were entered into fields that were not filled.4.5 Combining with Citations
The UG's Structured Output page states that Anthropic's models do not support using structured output and citations simultaneously.Structured outputs is incompatible with citations for Anthropic models. If you enable citations while
using structured outputs, the model will return a 400 error.
In this article's setup, when a document block with citations enabled was combined with
output_config.format in the same request, a ValidationException stating Citations cannot be enabled when output format is set. was returned in 0.45 seconds.4.6 Table of What Is Rejected and When
| What Is Rejected | When It Is Rejected | What the Caller Receives | Time Before It Returns | Where It Is Written | No Statement Found |
|---|---|---|---|---|---|
| Features of JSON Schema that are not supported | At the time of the request (schema validation) | 400 | Immediately | Request workflow on the UG's Structured Output page | — |
Absence of additionalProperties or values other than false | At the time of the request | 400 ValidationException | Approximately 0.44 to 0.48 seconds (in this article's configuration) | UG's Structured Output page | — |
Invalid pattern | At the time of the request | 400 ValidationException (Invalid regex in pattern field.) | Approximately 0.44 seconds (in this article's configuration) | UG's Structured Output page | — |
| 17 or more union-typed properties | At the time of the request | ValidationException | Immediately (approximately 0.52 seconds in this article's configuration) | Limits section on the UG's Structured Output page | — |
| 13 or more optional properties | During grammar compilation | ValidationException (Schema is too complex.) | Up to approximately 90 seconds (approximately 45 seconds in this article's configuration) | Limits section on the UG's Structured Output page | — |
| Using citations and structured output simultaneously | At the time of the request | 400 | Approximately 0.45 seconds (in this article's configuration) | Note section on the UG's Structured Output page | — |
minLength | Not rejected in this article's configuration | 200 response | — | The UG's Structured Output page lists it as unsupported | Reason why requests with minLength are accepted, and whether it is enforced |

5. Grammar Compilation and Caching
This section details the time required for grammar compilation and explains what the compiled grammar cache stores. In conclusion, there are five key points:- The initial request for a new schema may take up to approximately 90 seconds for grammar compilation. The UG says to set the client read timeout to 120 seconds or longer.
- The compiled grammar is cached for 24 hours from the first access. According to three AWS documents, this initial access is the starting point for the cache duration.
- The cache is used for the same schema in the same account. It is important to note that the unit is the account, as specified in the ML Blog.
- Changes to the schema structure invalidate the cache, while changing only the
nameanddescriptiondoes not. - The grammar cache is separate from prompt caching.
5.1 Initial Request and Read Timeout
The Limits section of the UG's Structured Output page describes compilation time as follows:Compilation time. The first request that uses a new schema compiles a grammar, which can take up to
approximately 90 seconds. Subsequent requests that use the same schema reuse the cached grammar and
return with standard inference latency. Set your client read timeout to at least 120 seconds so that
the first request does not time out during compilation.
Approximately 90 seconds is the stated maximum, and does not represent the time for each instance. In this article's setup, the initial request for a small schema with four items took 2.23 seconds, while the second request for the same schema took 1.28 seconds. The initial request for a schema with twelve optional properties took 53.10 seconds. This article reads that compilation takes longer as schemas become more complex.
No statement was found on whether compilation continues and grammar is cached within Amazon Bedrock when the caller cancels a request due to a read timeout. This is a
no statement was found state, and the search covered the two UG pages and the two ML Blog articles. This article reads that if the SDK is configured to automatically retry read timeouts, the canceled request may be resent with the same schema, resulting in a longer wait time for the caller, proportional to the number of retries.5.2 24 Hours, from First Access, for the Same Account
The Request workflow section of the UG's Structured Output page describes caching as follows:Caching – Successfully compiled grammars are cached for 24 hours from first access. Cached grammars are
encrypted with AWS-managed keys.
Subsequent requests – Identical schemas from the same account use cached grammars, resulting in
inference latency comparable to standard requests with minimal overhead.
The UG states that the same schema from the same account uses the cache. The two ML Blog articles explicitly state that the cache operates on an account basis. The ML Blog's October article states:
This cache is scoped to your account and lasts for 24 hours from first access.
The ML Blog's February article also states:
Cache scope: Grammars are cached per account for 24 hours from first access
Three AWS documents all refer to the 24-hour starting point as the initial access. Anthropic's Structured Output page gives last use as the starting point; Section 9.2 sets them side by side.
No statement was found on whether the cache key includes the Region. This is a
no statement was found state; the search covered the two UG pages, the two ML Blog articles, and Anthropic's Structured Output page. Furthermore, no information was found regarding how the cache is used for requests that are routed to multiple Regions in the inference profile.5.3 Invalidating the Cache
The ML Blog's October article states that changing the schema structure will invalidate the cache, while changes to only thename and description fields will not.Changing the structure of your JSON schema invalidates the cache and triggers a fresh compilation,
while changing only the name or description fields leaves the cached grammar intact.
The ML Blog's February article also mentions tool input schemas.
Changing the JSON schema structure or a tool’s input schema invalidates the cache, but changing only
name or description fields does not.
Anthropic's Structured Output page states that changing the set of tools within a request will invalidate the cache when using structured output and tools together. AWS documentation refers to a tool's input schema, while the Anthropic page refers to the set of tools in the request. The documentation differs in how it describes the conditions that trigger cache invalidation.
It was not possible to determine from the documentation whether the
name and description fields refer to the name and description in the Shape B JsonSchemaDefinition, or whether they also refer to the description of each individual item in the schema. In this article's setup, requests that modified either of these elements returned results in approximately the same amount of time as those that did not. This will be discussed further in Section 8.2.5.4 Separate from Prompt Caching
Prompt caching is a separate mechanism from grammar caching. No request field for configuring grammar caching was found in the API references, so this article reads that the caller does not configure it, while prompt caching is a different system where the caller sets checkpoints, and model cards provide model-specific information.Anthropic's Structured Output page states that when using structured output, a system prompt that describes the output format is automatically added. It also notes that changing
output_config.format will invalidate the prompt cache.Changing the output_config.format parameter will invalidate any prompt cache for that conversation
thread.
The same statement was not found in Amazon Bedrock's documentation. This is a
no statement was found state; the search covered the two UG pages, the two ML Blog articles, and 19 model cards. This article does not say that Amazon Bedrock behaves the same way, nor that it behaves differently.5.5 Cache Attribute Table
| Attribute | AWS Documentation | Anthropic Page | No Statement Found |
|---|---|---|---|
| Duration | 24 hours (UG, the two ML Blog articles) | 24 hours | — |
| Start Point | From first access (UG, the two ML Blog articles) | From last use | — |
| Scope | Same account (UG), per account (the two ML Blog articles) | — | Whether the Region is part of the key |
| What is invalidated | Schema structure, tool input schema (the ML Blog's February article) | Schema structure, set of tools in the request | Handling changes to an item's description |
| What is not invalidated | Changes to only name and description (the two ML Blog articles) | Changes to only name and description | — |
| Encryption | AWS-managed keys (UG) | — | — |
| Impact on prompt caching | — | Changing output_config.format invalidates the prompt cache | Handling within Amazon Bedrock |
6. Two Cases Outside the Guarantee, and Why to Check the Stop Reason First
This section outlines two scenarios where the output may not conform to the schema, even when structured output is enabled, and describes what the caller receives in those cases. The key takeaways are as follows:- If generation stops due to reaching
max_tokens, the JSON output will be truncated. The UG's Structured Output page states this explicitly. - In cases of model refusal, the output may not adhere to the schema. The Shape A stop reason
refusalis listed on the UG's Messages page. - In both scenarios, the response is returned as a response, rather than an error. In this setup,
max_tokensresponses returned HTTP 200 on four APIs (InvokeModel, Converse, ConverseStream, and the Messages API onbedrock-mantle). - The Shape B Converse
stopReasonenumeration does not includerefusal, and no statement was found on how a Claude refusal is returned in Converse. - Therefore, the caller should examine the stop reason before parsing the JSON, treating any reason other than
end_turndifferently.
6.1 max_tokens
The Note in the Limits section of the UG's Structured Output page states the following:Set the maximum number of response tokens high enough to contain the complete JSON object. For example,
use max_tokens for the InvokeModel API or maxTokens for the Converse API. If the response reaches the
token limit first, the model stops with a max_tokens stop reason and returns incomplete JSON, even when
structured outputs is enabled.
While the grammar constraints guide the output to align with the schema, a separate limit applies to the length of the output. In this article's setup, requests with the limit set to 20 tokens were truncated in InvokeModel, Converse, and ConverseStream.
{"category":"technical","priority":"high","summary":"N
All three returned an HTTP 200 status, with the stop reason indicated as
max_tokens. Python's json.loads produced a JSONDecodeError due to the incomplete JSON string. Similarly, the Messages API within bedrock-mantle returned a truncated JSON string with an HTTP 200 status, also indicating max_tokens as the stop reason.6.2 Model Refusal
The UG's Messages page listsrefusal as a Shape A stop reason value.refusal – The model was blocked by a content classifier before completing its response. The response
may contain partial content if the classifier fired mid-stream. See stop_details for additional
information about the restriction.
The same page says to branch on
stop_reason rather than stop_details.Branch on stop_reason, not on stop_details. The stop_details field is informational and can be null
even when stop_reason is "refusal".
Anthropic's Structured Output page notes that a refusal's output may not match the schema.
The output might not match your schema because the refusal message takes precedence over schema
constraints.
Anthropic's Structured Output page states that the HTTP status for a refusal is 200. In AWS documentation, the model cards for Claude Fable 5.1 and Claude Fable 5 describe the response when a classifier blocks a request, in the same words:
When a classifier blocks a request, the API returns a standard HTTP 200 response with stop_reason:
"refusal" and a stop_details object containing the restriction category.
This wording appears on the cards for Claude Fable 5.1 and Claude Fable 5, and is not present on any of the other 17 cards. No AWS statement giving the HTTP status of a refusal model by model was found for other models. This article's demo did not trigger a model refusal.
6.3 Converse's stopReason and a Disagreement Between AWS Documents
The API reference page for Converse lists the valid values for stopReason, and the MessageStopEvent page for ConverseStream gives the same list.end_turn | tool_use | max_tokens | stop_sequence | guardrail_intervened | content_filtered |
malformed_model_output | malformed_tool_use | model_context_window_exceeded
This list does not include
refusal. Similarly, the service model enumeration in the AWS SDK for Python (botocore) also lists the same nine values. However, the ML Blog's February article, within its section on best practices, recommends checking for refusals using stopReason.Check stopReason in every response. Two scenarios can produce non-conforming responses: refusals (when
the model declines for safety reasons) and token limits (when max_tokens is reached before completing).
Handle both cases in your code.
These two are in the state
the sources disagree. The API reference enumeration does not include refusal, while the ML Blog's February article says to check for refusals using stopReason. No statement was found on which stopReason value a Claude refusal returns in Converse. This is a no statement was found state; the search covered the API reference for Converse, ConverseStream, and MessageStopEvent, as well as the UG's Messages page, the UG page on guardrails with the Converse API, the SDK reference, and the two ML Blog articles. This article does not say that a refusal becomes content_filtered, nor that it becomes end_turn.6.4 Refusal Mid-Stream
The UG's Messages page describes a refusal mid-stream as follows:In streaming mode, the refusal arrives as the final message_delta event with stop_reason: "refusal";
any content blocks streamed before the refusal are valid partial output.
When a refusal occurs mid-stream, this article reads the data received up to that point as a partial JSON object. Partial output cannot be used directly as JSON.
6.5 Branches in the UG Example
The example on the UG's Claude page checks the stop reason before parsing.# Check the stop reason before parsing
This example's branching only involves
end_turn and max_tokens, and does not include a refusal branch. The two ML Blog articles say to handle both refusals and max_tokens. This article does not reproduce the branching structure of the UG example as a recommended approach.6.6 Values That Differ Even When the Output Matches the Schema
Anthropic's Structured Output page states that it does not guarantee the capitalization of stringenum and const values.Structured outputs don’t guarantee the capitalization of string enum and const values
Anthropic's documentation further states that in such cases, the response ends normally, without an error or a special stop reason. The same statement was not found in Amazon Bedrock's documentation. This is a
no statement was found state; the search covered the two UG pages and the two ML Blog articles.6.7 Branching on the Stop Reason
The caller checks the stop reason before parsing the JSON. The following example branches for Shape A.import json
def read_structured_output(body):
reason = body.get("stop_reason")
if reason == "end_turn":
text = next(b["text"] for b in body["content"] if b["type"] == "text")
return json.loads(text)
if reason == "max_tokens":
# Incomplete JSON: raise max_tokens and send the request again.
raise RuntimeError("truncated by max_tokens")
if reason == "refusal":
# The output may not match the schema. Read stop_details only for logging.
raise RuntimeError("model refusal: %s" % body.get("stop_details"))
# Any other value: do not parse; log it and decide in application code.
raise RuntimeError("unexpected stop_reason: %s" % reason)
For Shape B (Converse), check the
stopReason. Since the enumeration does not include refusal, this article recommends parsing only when end_turn is indicated, and treating all other values without parsing. This recommendation is not a statement from the sources; it is this article's reading of the disagreement in Section 6.3.6.8 Table by Outcome
| Outcome | HTTP | Shape A stop_reason | Shape B stopReason | Is the JSON Parseable | Where It Is Written | No Statement Found |
|---|---|---|---|---|---|---|
| Output Completed | 200 | end_turn | end_turn | Parsable | Example on the UG's Claude page | — |
| Output Limit Reached | 200 (four APIs in this article's setup) | max_tokens | max_tokens | Truncated, not parsable | Note on the UG's Structured Output page | — |
| Model Refusal | 200 (Anthropic's Structured Output page, Claude Fable 5.1 and Claude Fable 5 cards) | refusal (UG's Messages page) | Not listed | May not conform to the schema | UG's Messages page, Anthropic's Structured Output page | Value in Converse |
| Schema Rejection | 400 | No output from the model | No output from the model | — | UG's Structured Output page | — |
| Capitalization Differences | 200 | end_turn | end_turn | Parsable, but value differs from enum | Anthropic's Structured Output page | Handling in Amazon Bedrock |

7. Key Differences When Choosing an Entry Point
This section highlights how the features used in conjunction with structured output can affect the available entry points. In conclusion, there are four key distinctions:- Guardrails are not supported on
bedrock-mantlein any model card that has abedrock-mantlecolumn. - Citations and structured output cannot be used together for Anthropic models, according to the UG.
- Support varies depending on the model, endpoint, Region, and inference profile.
- For new applications,
bedrock-runtimeis recommended.
7.1 Guardrails
In the Capabilities and Features table of the model cards, thebedrock-runtime column of the 14 Active cards that have this column supports both structured output and Guardrails. Eleven cards list a bedrock-mantle column, and all of these support structured output but do not support Guardrails.No statement was found describing limitations when using structured output and Guardrails in the same request. This is a
no statement was found state; the search covered the UG's Structured Output page, the UG's Claude page, the UG page on guardrails with the Converse API, and the 19 model cards. The UG page on guardrails with the Converse API describes the stop reason when Guardrails intervene.The stopReason field in the response is set to guardrail_intervened.
No statement was found on whether the output conforms to the schema when Guardrails intervene.
7.2 Citations
As stated in Section 4.5, the UG's Structured Output page states that Anthropic models cannot use structured output and citations at the same time. Anthropic's Structured Output page also notes that using citations along withoutput_config.format returns a 400.7.3 Model, Endpoint, Region, Inference Profile
The UG's Structured Output page notes that structured output is unavailable for certain geographic cross-Region inference profiles.Some Geographic cross-Region inference profiles don't support structured outputs for every model. For
example, structured outputs aren't supported for Claude Haiku 4.5 through the India (in.anthropic)
inference profile. Check the model card for model-specific limitations.
The model card for Claude Haiku 4.5 also contains similar wording. However, the Supported APIs or features table on the UG's Structured Output page indicates that structured output is available without additional configuration for both cross-Region and batch inference. As mentioned in Section 3.5, it is also important to verify the API and Region compatibility for each endpoint through the model card.
7.4 Recommended Endpoints
The UG's Endpoint page recommends usingbedrock-runtime for new applications, and suggests using bedrock-mantle only when features exclusive to that endpoint are required. The UG's Claude page describes the role of bedrock-mantle as follows:The bedrock-mantle endpoint is designed for agentic applications that use server-side tools,
background inference, and stateful conversations.
Both endpoints support structured output. Therefore, this article reads that structured output alone does not decide the endpoint. If you require Guardrails, the cards in Section 7.1 point to
bedrock-runtime.7.5 Table for Selecting Entry Points
| Layer | What It Decides | What the Caller Receives | Where It Is Written | No Statement Found |
|---|---|---|---|---|
| Model Card API and Region Table | The entry points and Regions available for that model. | A response saying the model does not exist, for an entry point and Region where it is not offered (the 404 on bedrock-mantle in this article's setup) | 19 model cards | — |
| Model Card Capabilities Table | The structured output and Guardrails supported for each endpoint. | — | 19 model cards | Restrictions on using structured output and Guardrails together. |
| Inference Profile | Whether structured output can be used with the Geographic profile. | — | Important section on the UG's Structured Output page, Claude Haiku 4.5 card. | — |
| Citations Settings | Whether it can be used simultaneously with structured output. | 400 | Note on the UG's Structured Output page. | — |
8. What This Setup Showed
This section details observations made using the demo configuration created on October 30, 2026, separating the documented values from the observed values. The information presented here is a record of the results obtained using this configuration, and should not be interpreted as a performance comparison. Account IDs, ARNs, and request IDs have been redacted.8.1 Setup
Region is set to us-east-1. Rather than creating AWS resources, the script used AWS SDK for Python (boto3 and botocore version 1.43.122) to callbedrock-runtime's InvokeModel, Converse, and ConverseStream functions. The bedrock-mantle Messages API was called from the AnthropicBedrockMantle client within Anthropic's Python SDK.Within
bedrock-runtime, the model used was Claude Haiku 5.5, using the inference profile us.anthropic.claude-haiku-5-5. Thinking was disabled with {"type": "disabled"} so that, when the max_tokens limit was reached, the JSON output, not the thinking, would be cut off. The SDK retry count was fixed at one, and the read timeout was set to 150 seconds. Within bedrock-mantle, Claude Haiku 4.5 (anthropic.claude-haiku-4-5) was used; the reason for this is detailed in Section 8.6.To ensure that each execution generates a unique request and avoids the grammar cache of previous runs, a random suffix was appended to the names of schema items. The prompts were designed solely to extract items from a single support inquiry, and no model refusal was triggered.
Calls were made 24 times between 12:13 and 12:16 UTC on October 30, 2026, and an additional 4 times at 12:38 UTC.
8.2 Initial Request, Second Request, and Requests with a Changed Entry Point or Description
The following table presents the observed times for a schema with four items.| Request | Entry Point | Seconds | Stop Reason |
|---|---|---|---|
| Initial request for a new schema | InvokeModel | 2.23 | end_turn |
| Second request for the same schema | InvokeModel | 1.28 | end_turn |
| Third request for the same schema | InvokeModel | 1.36 | end_turn |
| Same schema | Converse | 1.34 | end_turn |
Request with only a property's description modified | InvokeModel | 1.34 | end_turn |
Request with only the name and description for Converse modified | Converse | 1.33 | end_turn |
| Request with one item added | InvokeModel | 1.67 | end_turn |
| Same schema, approximately 25 minutes after the initial request | InvokeModel | 1.89 | end_turn |
For the smaller schema, the difference between the initial request and the second request was approximately 1 second. A request that sent, as a string via Converse, the schema first sent with InvokeModel also returned in roughly the same amount of time as the second request. No statement was found on whether entry points with different shapes share a grammar cache. Given the difference of only about 1 second, it is impossible to definitively conclude, based on these observations alone, whether the cache was hit or missed. Furthermore, the 1.89 seconds observed for the request made approximately 25 minutes later should not be taken as evidence that the cache was still active.
8.3 Time and Wording of the Rejections
| Schema | Entry Point | Seconds | HTTP | What Was Returned |
|---|---|---|---|---|
| 13 Optional Fields | InvokeModel | 45.26 | 400 | ValidationException: compilation exceeded limits: Schema is too complex. |
| 13 Optional Fields | Converse | 44.94 | 400 | ValidationException: The model returned the following errors: compilation exceeded limits: Schema is too complex. |
| 12 Optional Fields | InvokeModel | 53.10 | 200 | end_turn response |
Missing additionalProperties | InvokeModel | 0.44 | 400 | ValidationException: output_config.format.schema: For 'object' type, 'additionalProperties' must be explicitly set to false |
Missing additionalProperties | Converse | 0.48 | 400 | Same error message as above, preceded by The model returned the following errors: |
pattern with Lookahead | InvokeModel | 0.44 | 400 | ValidationException: Invalid regex in pattern field: Quantifier '?' without preceding element |
| 17 Union Type Fields | InvokeModel | 0.52 | 400 | ValidationException: a message stating that the schema has 17 union-typed properties and that the limit is 16 |
minLength | InvokeModel | 1.57 | 200 | end_turn response |
| Citations and Structured Output | InvokeModel | 0.45 | 400 | ValidationException: Citations cannot be enabled when output format is set. Please disable citations on uploaded document blocks. |
The rejection of the 13 optional properties returned approximately 45 seconds after the request, not at request time. This matches the UG statement in Section 4.2: during compilation, up to approximately 90 seconds. The schema with exactly 12 was accepted, but the initial request took approximately 53 seconds. Even below the limit, the initial request can take long.
Converse also reported an error related to a request lacking the
additionalProperties field, specifically mentioning output_config.format.schema. The fields written in the Converse request are outputConfig.textFormat. This article reads this as the Converse request appearing to be mapped to the Shape A field inside Amazon Bedrock for validation. No statement describing this mapping was found.The schema with
minLength did not return a 400. The UG's Structured Output page lists string constraints (minLength, maxLength) as unsupported features and states that unsupported features return a 400 immediately. This observation contradicts two statements in the UG documentation. It is unclear from this single observation whether minLength was ignored or enforced. The returned summary was longer than 5 characters. This discrepancy is also mentioned in Section 9.6.8.4 JSON Cut Off by max_tokens, and the HTTP Status
As in Section 6.1, requests with the limit set to 20 tokens were truncated, resulting in HTTP 200 responses for all three operations (InvokeModel, Converse, and ConverseStream). The stop reason was max_tokens. For ConverseStream, the HTTP status reflected the state of the response when the stream was initially opened. The stop reason was included in the final messageStop event in the stream. In all three cases, json.loads failed.8.5 default and Required Fields That Allow null
As described in Sections 4.3 and 4.4, the optional property with default contained the default value in both requests. Schemas with 14 required fields that allow null values were accepted. In the first 300 characters of the recorded output, 6 fields contained words from the inquiry, and the next 4 fields were null. The data for subsequent fields was not recorded.8.6 The Messages API on bedrock-mantle
Initially, when specifying Claude Haiku 5.5 (anthropic.claude-haiku-5-5) on bedrock-mantle, both attempts returned an HTTP 404 not_found_error indicating that the model was not found. The Claude Haiku 5.5 card lists only us-gov-west-1 as a Region where bedrock-mantle is available, so the result matches the card's table.Therefore,
output_config.format was sent to Claude Haiku 4.5, which is offered on bedrock-mantle in us-east-1.| Request | Seconds | HTTP | Stop Reason | JSON |
|---|---|---|---|---|
| First request with the new schema | 2.64 | 200 | end_turn | Parsed successfully |
| Second request with the same schema | 1.11 | 200 | end_turn | Parsed successfully |
max_tokens set to 20 | 1.18 | 200 | max_tokens | Cut off and unable to parse |
The
bedrock-mantle Messages API accepted the output_config.format parameter. This is the opposite of the October 6, 2026 UG text in Section 9.8 (a 400), and matches the current UG text.8.7 What Was Not Tried
- The
bedrock-runtimeMessages API was not tested. - No model refusal was triggered. Which
stopReasona refusal returns in Converse remains in the stateno statement was found, as in Section 6.3. - Guardrails in combination with structured output were not tested.
- The behavior of the cache after 24 hours was not tested.
- A schema rejection on ConverseStream or InvokeModelWithResponseStream was not tested.
9. Discrepancies, Omissions, and Changes in the Documents
This section lists where the sources differ, what was not found in them, and what changed over time. This article does not decide that either source is wrong.9.1 Limit on Optional Properties - 12 and 24
The UG's Structured Output page gives the limit on optional properties as 12, the total within one schema. Anthropic's Structured Output page gives the limit as 24 and states how it is counted.Total optional parameters across all strict tool schemas and JSON output schemas.
For Anthropic's page, the number 24 refers to the combined total of all strict tool schemas and JSON output schemas within a single request. For UG, the number 12 is the combined total, including nested objects, within a single schema. Because both the values and the counting units differ,
the sources disagree. In Amazon Bedrock, in this article's setup, a schema with 13 was rejected and one with 12 was accepted.9.2 Cache Starting Point - First Access and Last Use
The UG and the two ML Blog articles give first access as the 24-hour starting point. Anthropic's Structured Output page states:Automatic caching: Compiled grammars are cached for 24 hours from last use, making subsequent requests
much faster.
Because the starting points are opposite,
the sources disagree. This article reads that, counted from first access, the cache expires 24 hours later even if it keeps being used.9.3 Compilation Time - About 90 Seconds and 180 Seconds
UG states that the initial request compilation may take up to approximately 90 seconds, and recommends setting the read timeout to 120 seconds or more. Anthropic's Structured Output page specifies a compilation timeout of 180 seconds.As a final stop-gap, the API also enforces a compilation timeout of 180 seconds.
The value provided by UG is the potential compilation time, while the value on Anthropic's Structured Output page indicates the timeout duration. These are different types of values, so one cannot be used to replace the other. The Amazon Bedrock client timeout should follow the guidance provided by UG.
9.4 Supported Models - "all" and "Support varies"
The What's New announcement of October 20, 2026, states the following:Amazon Bedrock now supports structured outputs for all Anthropic Claude models across both the
bedrock-runtime and the bedrock-mantle endpoint.
The UG's Claude page states the following:
Structured outputs is available across the Claude Sonnet, Opus, Haiku, Fable, and Mythos model
families. Support varies by model and endpoint.
The model cards list fifteen "Active" models as supporting structured output. Legacy Claude Sonnet 4.5 is also listed as supported. However, the cards for Legacy Claude Opus 4.1 (scheduled to be discontinued on January 8, 2027) and Claude Sonnet 4 (which was discontinued on October 14, 2026) do not mention structured output in either the "Supported" or "Not Supported" columns. The card for Claude 3 Haiku does not include a "Capabilities" section.
Anthropic's Structured Output page lists 17 model IDs as compatible in its page metadata, and in the "Availability" section of the same page, it states that structured outputs are available on every model, and its availability table links "All models" to the models overview. The models on that overview are among the 17, so this article does not treat the list and the sentence as a disagreement.
This article does not quote the announcement's all as the specification. Instead, verify whether structured output is listed as "Supported" on the card for the specific model you are using.
9.5 General Availability Timeline
When arranged chronologically, Anthropic's Release Notes and AWS's What's New announcements are as follows:- November 14, 2025: Anthropic's Release Notes state that they released structured output in beta for the Claude API, targeting Claude Sonnet 4.5 and Claude Opus 4.1.
- January 29, 2026: Anthropic's Release Notes state that the beta ended on the Claude API, and in the same item state that it is still in beta on Amazon Bedrock.
- February 4, 2026: AWS's What's New announces the general availability of structured output for the Claude 4.5 models and select open-weight models on Amazon Bedrock.
- April 1, 2026: AWS's What's New announces expansion to the AWS GovCloud (US) Regions.
- October 20, 2026: AWS's What's New announces support for all Claude models and
bedrock-mantle.
Structured outputs remain in beta on Amazon Bedrock and Microsoft Foundry.
Between Anthropic's text of January 29, 2026, and AWS's text of February 4, 2026, the status changed in six days. For the general availability date on Amazon Bedrock, this article uses the date of AWS's What's New. Claude Opus 4.1, which was part of the November 2025 beta on the Claude API, is not currently listed as supporting structured output on the Amazon Bedrock cards.
9.6 Converse's Refusal, and minLength
As mentioned in Section 6.3, the enumerated list of Converse's stopReason values does not include refusal. However, the ML Blog's February article states that refusals should be checked using stopReason. This is the state the sources disagree, and the value in Converse is in the state no statement was found.As in Section 8.3, the UG lists
minLength as an unsupported feature and states that unsupported features return a 400 immediately, but in this article's setup a 200 response was returned. There is a discrepancy between the information presented in the documentation and the observed results. No documentation was found that explains the reason for this.9.7 Statements of Benefits and Statements of Limitations
The UG's Claude page lists the following benefits:Every response is valid JSON, which eliminates parsing errors and exceptions.
Schema violations do not require retry logic.
The What's New announcement of October 20, 2026, also states that you can receive JSON that conforms to the schema, without requiring any custom parsing, retries, or post-processing. However, the UG's Structured Output page states, as detailed in Section 6.1, that the JSON is truncated when the
max_tokens limit is reached. As the specification, this article quotes the statements of limitations. This article reads the statements of benefits as statements about responses in which neither max_tokens nor a model refusal occurs.9.8 What Changed - The 400 on bedrock-mantle
The UG's Endpoint page saved in the Internet Archive's Wayback Machine on October 6, 2026, stated:In particular, structured outputs (the output_config.format parameter) are not supported on
bedrock-mantle — requests that include output_config.format are rejected with a 400 error.
The UG's Claude page saved on July 2, 2026, also stated that the
bedrock-mantle Messages API does not support structured output, and that output_config.format is rejected with a 400. The models listed on that page were Claude Sonnet 4.5, Claude Haiku 4.5, Claude Opus 4.5, and Claude Opus 4.6.The UG's Endpoint page as of October 30, 2026, states, as described in Section 3.1, that
output_config.format can be used on both endpoints. As outlined in Section 8.6, the bedrock-mantle Messages API also accepted output_config.format. The wording changed after the capture of October 6, 2026 (06:32 UTC) and no later than the capture of October 20, 2026 (03:19 UTC); the four captures from October 20, 2026, to October 23, 2026, all contain the current wording. Reading this as the same time as the October 20, 2026 announcement is this article's inference. Materials or articles stating that structured output on bedrock-mantle returns a 400 match the UG text of October 6, 2026. Before concluding there is an error, it is important to verify the date on which the information was written.9.9 Constraints Specific to the Anthropic Documentation
The following information was found on Anthropic's Structured Output page and was not found in Amazon Bedrock materials. The search included the two UG pages, the two ML Blog articles, and 19 model cards. This is ano statement was found state. This article does not say that Amazon Bedrock behaves the same way, nor that it behaves differently.- The case (uppercase/lowercase) of strings within
enumandconstis not guaranteed. - Output is structured with required fields appearing before optional properties.
- Prefilling the start of the assistant turn cannot be used with JSON output.
- A property that asks for the thinking process can lead to a
reasoning_extractionrefusal. - A system prompt that describes the output format is automatically added.
- Changing
output_config.formatinvalidates the prompt cache. - Up to 20 strict tools per request.
9.10 Items Not Found in the Documentation
The following items were not found in the documentation. The search included the documentation from Section 1.3, focusing on the pages relevant to each item.- Which
stopReasonvalue a Claude refusal returns in Converse and ConverseStream - The constraints when using structured output and Guardrails in the same request, and whether the output conforms to the schema when Guardrails intervene
- Whether the Region is part of the grammar cache key
- Whether the Shape A and Shape B entry points share the grammar cache
- Whether compilation continues for a request cut off by a read timeout
- Whether changing
output_config.formatinvalidates the prompt cache on Amazon Bedrock - The limit on the number of strict tools on Amazon Bedrock
- How much of the JSON is complete at any point during a stream
10. Failure Modes
This section lists potential failure scenarios, categorized by symptoms, causes, and methods for verification.- Passing a Shape A schema object to Converse and the request fails: Shape B requires the
schemato be a JSON string. Convert it to a string using methods likejson.dumpsbefore passing it. - Initial request fails due to client timeout: Compiling a new schema can take up to approximately 90 seconds. Increase the read timeout to 120 seconds or more, as per the UG. The wait time may be even longer due to overlap with the SDK's automatic retry mechanism.
- Schema errors returned after tens of seconds: More than 12 optional properties are present. This rejection occurs during grammar compilation. Either move fields to the
requiredsection, or make them required fields that allownullvalues. However, union-typed properties are limited to 16. - Schemas without
additionalPropertiesresult in a 400 error: For structured output, ensure that allobjecttypes includeadditionalProperties: false. This applies to nestedobjecttypes as well. - A
JSONDecodeErroroccurs during parsing: The stop reason is usuallymax_tokens(a model refusal can also leave output that does not parse; Section 6.2). Check the stop reason before parsing and increase themax_tokensvalue before resending. - HTTP 200 is returned, but the output does not conform to the schema: The stop reason may be
refusal. In Shape A, check thestop_reason. In Shape B's Converse, do not parse anything other thanend_turn. - Model not found on
bedrock-mantle: One cause is that the model is not offered onbedrock-mantlein that Region (Section 8.6). Check thebedrock-mantleRegion table in the model card. - Enabling citations results in a 400 error: Anthropic models do not support using structured output and citations simultaneously.
- Attempting to use Guardrails while selecting
bedrock-mantle: The model card indicates thatbedrock-mantledoes not support Guardrails. - Avoiding
bedrock-mantlebased on outdated documentation: The UG of October 6, 2026, stated that it returns a 400, but the UG from October 30, 2026, states that it is available on both endpoints. Verify the date of the documentation.
11. Frequently Asked Questions About Claude Structured Outputs on Amazon Bedrock
Q1. If structured output is enabled, will the response always be a JSON object that strictly adheres to the schema?
There are two scenarios where this is not guaranteed. First, if themax_tokens limit is reached, the JSON output is truncated mid-response, as the UG's Structured Output page states. Second, in cases where the model refuses, the output may not adhere to the schema, as Anthropic's Structured Output page states. Both cases can come back as an HTTP 200 response (for the HTTP status of a refusal, see Section 6.2), so check the stop reason before parsing.Q2. Can the schema be defined in the same way for both InvokeModel and Converse?
No, they are not the same. In InvokeModel, you write a JSON object in theschema field within output_config.format. In Converse, you write a JSON string in the schema field within outputConfig.textFormat.structure.jsonSchema. Furthermore, the names of the fields for specifying the stop reason are different: stop_reason and stopReason.Q3. Are structured outputs available for all Claude models?
The What's New update of October 20, 2026, states that structured outputs are available for all Claude models. However, the UG's Claude page indicates that support varies depending on the model and endpoint. In the model cards, all 15 Active cards list it as Supported, but there is no mention of structured output for either the "Legacy" Claude Opus 4.1 or the discontinued Claude Sonnet 4. Verify compatibility by checking the model card for the specific model you intend to use.Q4. If there is a problem with the schema, will an error be returned immediately?
If there are issues with the schema, errors may be returned immediately, or they may be delayed. According to the UG, unsupported features, the absence ofadditionalProperties, invalid pattern definitions, and 17 or more union-typed properties return an error immediately at request time. However, in this article's setup, minLength, an unsupported feature, did not return a 400. Schemas with 13 or more optional properties are rejected during grammar compilation and, according to the UG, can take up to approximately 90 seconds to return an error. In this article's setup, it took approximately 45 seconds.Q5. Why does the second request tend to be faster?
According to the UG, this is because the grammar compiled during the initial request is cached. UG specifies that the cache duration is 24 hours from the first access, and applies when the same schema is used for the same account. The ML Blog's February and October articles add that changing the schema structure invalidates the cache, while changing only name or description fields does not.Q6. Is the grammar cache the same as prompt caching?
They are different. Amazon Bedrock manages the grammar cache, and no request field for configuring it was found in the API references. Prompt caching is a mechanism where the caller sets checkpoints. Anthropic's Structured Output page states that changingoutput_config.format invalidates the prompt cache, but the same statement was not found in Amazon Bedrock's documentation.Q7. If the model refuses in Converse, what will the stopReason be?
This information was not found in the documentation. The stopReason enumeration in the API reference does not include refusal. However, the ML Blog's February article states that you should check for refusals using stopReason. This article's reading is that, in Converse, you parse only on end_turn and do not parse any other value.Q8. Can structured output also be used with bedrock-mantle?
Yes, for models whose card lists bedrock-mantle, in the Regions the card lists. The UG's Endpoint page states that both endpoints support output_config.format. Furthermore, in this article's setup, the bedrock-mantle Messages API also accepted output_config.format. However, the UG of October 6, 2026, stated that it returns a 400 error. Be sure to check the model card to confirm whether the model is available with bedrock-mantle in that Region.Q9. What should you do to write more than 12 fields that can be omitted?
If you need to specify more than 12 optional properties, the UG's Structured Output page describes listing those fields inrequired and making their type allow null, such as "type": ["string", "null"]. Fields that cannot be filled in will then contain null. However, because fields that allow null are considered union types, the maximum number is 16. This article reads that other anyOf fields also count toward the same limit of 16.Q10. Will a value be assigned if you use the default keyword?
No, it is not guaranteed. The UG's Structured Output page states that while default is accepted, it is not enforced and only serves as a hint when the model generates a value. Unless specified as required, it is counted as an optional field, with a maximum limit of 12.12. Summary
- There are two places to write the schema by request shape, and four by entry point. Shape A (InvokeModel and the Messages API on two endpoints) requires a JSON object in
output_config.format. Shape B (Converse and ConverseStream) requires a JSON string inoutputConfig.textFormat.structure.jsonSchema.schema. - The model card's API table and Region table determine which entry points are available.
- According to the UG, unsupported features, the absence of
additionalProperties, invalidpatternspecifications, and 17 or more union-typed properties immediately result in a 400 error. Of the cases tested in this article's setup, onlyminLengthdid not return a 400. Schemas with 13 or more optional properties are rejected during grammar compilation, which can take up to approximately 90 seconds to return. - Grammar compilation can take up to approximately 90 seconds. The UG documentation recommends setting a read timeout of 120 seconds or longer. The compiled grammar is cached for 24 hours, starting from the first access in the same account.
max_tokensand model refusals are returned as responses, not errors. Tell them apart by the stop reason, not the HTTP status, and check the stop reason before parsing. The value of a refusal in Converse was not found in the documentation.- AWS documentation and Anthropic documentation provide different specifications for the maximum number of optional properties (12 and 24, respectively), the start of caching (first access versus last use), and the compilation time (approximately 90 seconds versus 180 seconds). Read the Amazon Bedrock values from the AWS documents.
- The structured output for
bedrock-mantlewas documented as returning a 400 error in the UG of October 6, 2026, and is documented as usable in the UG of October 30, 2026. Verify the documentation's date.
13. References
- Amazon Bedrock User Guide: Get validated JSON results from models
- Amazon Bedrock User Guide: Structured outputs for Anthropic Claude models
- Amazon Bedrock User Guide: Inference endpoints supported by Amazon Bedrock
- Amazon Bedrock User Guide: Request and Response (Anthropic Claude Messages API)
- Amazon Bedrock User Guide: Fallback credit for refused requests (beta)
- Amazon Bedrock User Guide: Use a guardrail with the Converse API
- Amazon Bedrock User Guide: Anthropic model cards
- Amazon Bedrock User Guide: Claude Haiku 5.5 model card
- Amazon Bedrock User Guide: Claude Haiku 4.5 model card
- Amazon Bedrock User Guide: Claude Sonnet 5.5 model card
- Amazon Bedrock User Guide: Claude Fable 5.1 model card
- Amazon Bedrock User Guide: Claude Fable 5 model card
- Amazon Bedrock User Guide: Claude Sonnet 4.5 model card
- Amazon Bedrock User Guide: Claude Opus 4.1 model card
- Amazon Bedrock User Guide: Claude Sonnet 4 model card
- Amazon Bedrock API Reference: Converse
- Amazon Bedrock API Reference: ConverseStream
- Amazon Bedrock API Reference: MessageStopEvent
- Amazon Bedrock API Reference: OutputConfig
- Amazon Bedrock API Reference: OutputFormat
- Amazon Bedrock API Reference: OutputFormatStructure
- Amazon Bedrock API Reference: JsonSchemaDefinition
- Amazon Bedrock API Reference: ToolSpecification
- What's New: Structured outputs now available in Amazon Bedrock
- What's New: Amazon Bedrock now supports structured outputs to AWS GovCloud (US) Regions
- What's New: Structured outputs for Claude models available on Amazon Bedrock
- AWS Machine Learning Blog: Structured outputs on Amazon Bedrock: Schema-compliant AI responses
- AWS Machine Learning Blog: Structured outputs for Anthropic Claude models on Amazon Bedrock
- Claude Platform Docs: Structured outputs
- Claude Platform Docs: Stop reasons and fallback
- Claude Platform Docs: Claude in Amazon Bedrock (Opus 4.7 and later)
- Claude Platform Docs: Release notes
- Internet Archive Wayback Machine: Inference endpoints supported by Amazon Bedrock, captured on 2026-10-06
- Internet Archive Wayback Machine: Inference endpoints supported by Amazon Bedrock, captured on 2026-10-20
- Internet Archive Wayback Machine: Structured outputs for Anthropic Claude models, captured on 2026-07-02
References:
Tech Blog with curated related content
Written by Hidekazu Konishi