Un error HTTP 400 al utilizar Claude en Amazon Bedrock puede deberse a un cuerpo de solicitud incompatible, un identificador de modelo incorrecto o una opción que ese modelo no admite. Pero también puede indicar un problema de firma, autorización o cuota. Antes de tocar la configuración, conserva el código de excepción y su mensaje completo: son los datos que permiten elegir una solución.
Si el mensaje es ValidationException, empieza por comprobar la operación que invocas y el modelo o perfil elegido. Si es ServiceQuotaExceededException, revisa la cuota de la cuenta: AWS también devuelve 400 para esta excepción en InvokeModel y contempla volver a enviar la solicitud más tarde. No tendría sentido modificar el JSON por ese motivo. La referencia de InvokeModel y el catálogo de errores de Bedrock en español distinguen estos casos.
Esta guía recoge la documentación consultada el 21 de septiembre de 2026. Los ejemplos sirven para aislar el fallo; no se han ejecutado contra una cuenta de AWS.
Empieza por el mensaje que acompaña al 400
Anota la región, la operación o URL utilizada, el identificador del modelo y, si está disponible, el identificador de la solicitud. En Claude Code, añade la versión del cliente y consulta /status para saber qué proveedor está activo. Si hay una pasarela entre el cliente y AWS, comprueba también qué error devolvió realmente el servicio de destino: la pantalla del cliente puede mostrar solo una descripción abreviada.
| Mensaje o código que recibes | Qué comprobar primero | Qué no conviene hacer |
|---|---|---|
Malformed input request, extraneous key o extra inputs are not permitted | Campos admitidos por la API y el modelo; opciones beta añadidas por el cliente | Reenviar el mismo cuerpo sin cambiar nada |
The provided model identifier is invalid | Identificador exacto, región y API de destino | Añadir un prefijo geográfico por intuición |
on-demand throughput isn't supported | Necesidad de un perfil de inferencia compatible | Seguir usando el ID base del modelo |
| Mensaje sobre longitud o límites de tokens | Tamaño de la entrada y salida solicitada | Reducir solo el tiempo de espera |
Mensaje sobre thinking o bloques de herramientas | Modo de razonamiento, parámetros e historial | Borrar toda la conversación sin identificar el turno conflictivo |
| Mensaje sobre retención o detección de abusos | Política efectiva de la cuenta y requisitos del modelo | Activar una política para toda la cuenta como prueba improvisada |
IncompleteSignature, RequestExpired o NotAuthorized | Firma, vigencia de la solicitud o autorización indicada | Tratarlo como un error del texto enviado al modelo |
ServiceQuotaExceededException | Cuota de servicio y consumo de la cuenta | Dar por hecho que todo 400 es un fallo de formato |
AWS documenta distintas causas de ValidationException, incluidas algunas relacionadas con autorización. Por tanto, el número 400 no descarta un problema de permisos. En cambio, tampoco justifica ampliar permisos si el mensaje señala un campo no admitido. Utiliza la guía de AWS para ValidationException para contrastar el texto concreto.
Comprueba que el cuerpo corresponde a la API que estás usando
Dos solicitudes pueden llevar el mismo mensaje para Claude y necesitar estructuras diferentes. Lo decisivo es el punto de conexión y la operación, no que ambas se anuncien como compatibles con Claude.
| Interfaz | Dónde se indica el modelo | Forma del texto y límite de salida |
|---|---|---|
Bedrock Runtime: Converse | Parámetro modelId de la operación | content: [{"text": "..."}] e inferenceConfig.maxTokens |
Bedrock Runtime: InvokeModel, formato Messages nativo de Claude | Parámetro modelId de la operación | content: [{"type": "text", "text": "..."}], max_tokens y anthropic_version en el JSON |
API compatible con Anthropic: /anthropic/v1/messages | Campo model del cuerpo | Contrato de Messages y cabecera HTTP anthropic-version |
En Converse, las instrucciones de sistema se envían en el campo system, separado de messages. El formato Messages nativo de Claude también separa system de los mensajes con rol user o assistant. No pegues un mensaje con rol system procedente de otro formato ni combines inferenceConfig con el cuerpo nativo de InvokeModel.
Las referencias de Converse, Messages nativo de Claude y la API compatible con Anthropic describen contratos distintos. Esta última existe en los puntos de conexión bedrock-runtime y bedrock-mantle: no todas las llamadas de Bedrock necesitan anthropic_version dentro del JSON. Si utilizas una pasarela de terceros, consulta el contrato de su URL concreta.

Aísla el problema con una solicitud mínima
Elige primero un modelo o perfil al que tu cuenta tenga acceso en la región de la llamada. El siguiente ejemplo presupone que ya tienes configuradas las credenciales y que has definido AWS_REGION y BEDROCK_MODEL_ID con valores válidos para tu cuenta; no propone un ID universal.
pythonimport os import boto3 from botocore.exceptions import ClientError runtime = boto3.client( "bedrock-runtime", region_name=os.environ["AWS_REGION"], ) try: response = runtime.converse( modelId=os.environ["BEDROCK_MODEL_ID"], messages=[{ "role": "user", "content": [{"text": "Responde solo: OK"}], }], inferenceConfig={"maxTokens": 64}, ) print(response["output"]["message"]) except ClientError as exc: error = exc.response.get("Error", {}) meta = exc.response.get("ResponseMetadata", {}) print({ "code": error.get("Code"), "message": error.get("Message"), "http_status": meta.get("HTTPStatusCode"), "request_id": meta.get("RequestId"), }) raise
Si tu integración utiliza InvokeModel con el formato Messages nativo, la llamada equivalente cambia de estructura. Reutiliza el cliente runtime anterior y envía un cuerpo como este:
pythonimport json response = runtime.invoke_model( modelId=os.environ["BEDROCK_MODEL_ID"], contentType="application/json", accept="application/json", body=json.dumps({ "anthropic_version": "bedrock-2023-05-31", "max_tokens": 64, "messages": [{ "role": "user", "content": [{"type": "text", "text": "Responde solo: OK"}], }], }), )
No añadas todavía herramientas, historial, guardrails, opciones de muestreo o razonamiento. Si la solicitud mínima funciona, recupera esas funciones una a una hasta identificar qué cambio provoca el rechazo. Si también falla, el mensaje obtenido permite seguir investigando el modelo, la región o la cuenta sin atribuir el problema a un historial complejo.

Revisa el modelo y el perfil sin inventar prefijos
Un modelo puede estar disponible en Bedrock y, aun así, no aceptar la modalidad de invocación que has elegido. Cuando el error indica que no admite rendimiento bajo demanda, comprueba si debes utilizar un ID o ARN de perfil de inferencia en lugar del ID base del modelo. Verifica el perfil para la región desde la que llamas y para tu cuenta.
En Claude Code hay otra distinción importante: un identificador válido para Invoke no tiene por qué ser válido para Mantle. La documentación actual indica que Mantle utiliza sus propios ID anthropic.*; un perfil de Invoke como us.anthropic.* no es un ID de modelo de Mantle. Antes de cambiar una variable, consulta /status y revisa cómo está configurada la conexión. Configuración oficial de Claude Code en Bedrock.
Claude Code puede preferir perfiles geográficos al resolver el modelo. Si no puede consultar la disponibilidad, aplicar un prefijo no garantiza que el resultado exista y puede acabar en un 400. La variable ANTHROPIC_BEDROCK_REGION_PREFIX, disponible desde la versión 2.1.224, expresa una preferencia; no sustituye la comprobación de un perfil ni convierte us. o global. en soluciones universales.
Si el mensaje menciona autorización, comprueba la identidad con la que se ejecuta el cliente y los permisos necesarios para la operación y los recursos elegidos. Una restricción por ubicación de la cuenta o país no se resuelve necesariamente cambiando la región en el código.
Cuando falla Claude Code: opciones beta, herramientas e historial
Si una llamada sencilla funciona y Claude Code falla, compara lo que añade el cliente. Empieza por claude --version y contrasta tu versión con los requisitos de la función que estás usando. Una incidencia antigua de GitHub no demuestra que la misma versión o el mismo fallo sigan vigentes hoy.
Un campo beta llega sin la cabecera que lo habilita
Una pasarela puede reenviar campos experimentales y eliminar anthropic-beta. El servicio de destino recibe entonces una combinación que no reconoce. Si admite esa función, la corrección consiste en conservar los campos y cabeceras correspondientes durante el tránsito. Si no la admite, puedes desactivar las capacidades experimentales del cliente como medida de compatibilidad. La documentación de errores de Claude Code explica esta diferencia.
Para iniciar una sesión desde una terminal compatible con esta sintaxis:
bashCLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1 claude
Este ajuste elimina cabeceras beta específicas de Anthropic y campos beta de los esquemas de herramientas. Conserva los campos estándar, incluido cache_control: no equivale a desactivar toda la caché. También desactiva la búsqueda de herramientas MCP y carga las herramientas por adelantado; desde la versión 2.1.227, una configuración administrada puede mantener esa búsqueda. Revisa la definición vigente de la variable y abre un proceso nuevo en el entorno donde hayas aplicado el cambio.
Úsalo cuando el mensaje apunte a opciones beta rechazadas. No arregla un perfil inexistente, una cuota agotada ni una política de retención incompatible. Si el canal que utilizas es el de LaoZhang API, su guía específica para el 400 de Claude Code con AWS recoge la configuración de ese servicio; no sustituye los ajustes de una cuenta nativa de AWS.
El rechazo afecta a herramientas o razonamiento
Un error de esquema exige revisar la definición de la herramienta y los campos que admite el modelo. Si el mensaje señala una discordancia entre bloques de tool_use, resultados de herramientas o razonamiento en el historial, Claude Code recomienda volver a un punto anterior al turno problemático mediante /rewind o pulsando Esc dos veces. Es una solución para ese historial concreto, no para errores de región o permisos. Errores de bloques de herramientas y razonamiento.
Tampoco conviene aplicar «desactiva thinking» como consejo general. AWS documenta modelos que requieren razonamiento adaptativo y rechazan thinking.type: enabled o disabled con un 400. En el razonamiento extendido convencional, el presupuesto debe ser inferior a max_tokens, pero el razonamiento intercalado tiene una excepción explícita. Comprueba el modelo y el modo que utilizas en la documentación de razonamiento de Claude para Bedrock antes de reutilizar parámetros de otra integración.
Si el mensaje exige una política de retención
En algunos modelos, la incompatibilidad entre la retención requerida y la política efectiva de la cuenta puede provocar ValidationException en bedrock-runtime. Esto requiere una decisión sobre el uso de datos, además de una corrección técnica.
Según la documentación actual de AWS sobre retención, las configuraciones nuevas deben usar aws_review. El valor provider_data_share es heredado y actualmente no implica enviar el contenido al proveedor del modelo. La revisión se realiza dentro de AWS; para los modelos Fable que la página identifica, la conservación puede llegar a 30 días. No interpretes tutoriales antiguos sobre «compartir con Anthropic» como una descripción de la política actual.
Comprueba con el administrador estos tres puntos antes de cambiar nada:
- El modo que exige exactamente el modelo y los modos permitidos para esa cuenta.
- La política efectiva en la región de la solicitud. En Bedrock Runtime, el ajuste se aplica a la cuenta, no a un proyecto aislado.
- Si existe una aprobación explícita de retención cero para ese modelo. Algunas cuentas aprobadas pueden utilizar
none; no es una excepción disponible por defecto para todas.
Heredar una configuración o utilizar un valor predeterminado no garantiza retención cero. Si la política que necesita el modelo no encaja con los requisitos de tu organización, detén esa ruta y evalúa una alternativa compatible. No cambies una política de toda la cuenta solo para comprobar si desaparece el 400.
Da el problema por resuelto cuando puedas explicar el cambio
Una respuesta correcta a la solicitud mínima demuestra que esa combinación de región, modelo, cuenta y cuerpo funciona en ese momento. Para cerrar el diagnóstico, repite después la operación que fallaba con las funciones necesarias y confirma qué cambio eliminó el error.
Si persiste, prepara un caso reproducible con la operación o URL, región, ID de modelo o perfil, versión del SDK o cliente, código y mensaje completos e identificador de solicitud. Sustituye el contenido privado por texto de prueba y elimina credenciales antes de compartirlo. Indica si el fallo aparece también sin herramientas e historial: esa diferencia suele ser más útil que una captura con «400 Bad Request».
Para decidir el siguiente paso, separa las causas: un cuerpo inválido necesita una corrección; una cuota requiere revisar sus límites y condiciones de reintento; un fallo transitorio puede justificar esperas y nuevos intentos. La guía sobre cuándo reintentar una API de LLM y cuándo cambiar de modelo desarrolla esa elección. El objetivo es que cada reintento tenga un motivo, en lugar de repetir una solicitud que ya sabes que el servicio rechaza.



