How to Fix Azure AI Translator Setup & API Errors
Why This Is Happening
I've seen this exact problem on dozens of Azure setups: you get your Azure AI Translator resource provisioned, paste your API key into the app, hit send , and nothing works. Maybe you get a 401 Unauthorized. Maybe a 400 Bad Request that tells you absolutely nothing useful. Or your document translation job just silently hangs in a "Running" state for hours. I know how frustrating that is, especially when it's blocking a production deployment.
Azure AI Translator (now officially called Azure Translator in Foundry Tools) is a cloud-based neural machine translation service that powers thousands of Microsoft products worldwide. It supports text translation, synchronous and asynchronous document translation, and custom domain-specific models through Custom Translator. That's a lot of moving parts , and each one has its own failure modes.
The core reason most people hit errors isn't the translation engine itself. It's the authentication layer, the endpoint configuration, or a missing dependency like Azure Blob Storage for batch document translation. Microsoft's error messages for these failures are notoriously unhelpful. A 403 Forbidden from the Translator REST API could mean your key is wrong, your endpoint region doesn't match your resource region, your resource is in a disabled state, or your request headers are malformed. The message won't tell you which one.
There are also newer failure patterns introduced with the 2025-10-01-preview API version, which added LLM-based translation (GPT-4o, GPT-4o mini) and adaptive custom translation. Teams that upgraded their API version without reading the preview migration guide are hitting breaking changes they didn't expect, different request body schemas, new required parameters, and changed response formats.
Document translation adds another layer of complexity. Asynchronous batch translation requires an Azure Blob Storage account with properly configured source and target containers. If your SAS tokens are expired, if your managed identity doesn't have Storage Blob Data Contributor rights, or if your container names have uppercase letters (yes, that breaks it), the job will fail in ways that are hard to debug.
This guide walks through all of it, from quick authentication fixes to deep-dive document translation debugging. Browse all Microsoft fix guides →
The Quick Fix, Try This First
Before digging into configuration and storage accounts, do this one check first. It resolves about 60% of Azure AI Translator errors I see.
Open the Azure Portal, navigate to your Translator resource, and go to Keys and Endpoint in the left sidebar. You'll see two things that must match exactly in your code: the API key (either KEY 1 or KEY 2) and the Endpoint URL. The single most common mistake? Developers copy the Cognitive Services global endpoint (https://api.cognitive.microsofttranslator.com) from a tutorial instead of using the region-specific endpoint shown on their own resource page.
Here's what a correct REST call looks like with the right headers:
POST https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&to=fr
Ocp-Apim-Subscription-Key: YOUR_KEY_HERE
Ocp-Apim-Subscription-Region: eastus
Content-Type: application/json; charset=UTF-8
[{"Text": "Hello, world!"}]
Notice the Ocp-Apim-Subscription-Region header. If your Translator resource is in eastus and you omit that header, or put the wrong region, you get a 401 even with a valid key. That header is mandatory for single-service resources. It's optional only if you're using a multi-service Cognitive Services resource, and even then the behavior differs by API version.
Copy your exact region string from the Overview page of your resource. It'll be something like eastus, westeurope, or australiaeast. Use that string verbatim in the header, no spaces, all lowercase.
If you're using the Azure AI Translator service through the new Microsoft Foundry portal (released November 2025), you can test translations directly in the built-in playground without writing any code. Go to foundry.azure.com, select your project, open the Translator tool, and run a test translation there first. If it works in the portal but not in your code, the problem is definitely in your request headers or body, not the resource itself.
Go to the Azure Portal at portal.azure.com and search for your Translator resource by name. Click into it and select Overview from the left menu. Note the Location field, this is your region.
Now go to Keys and Endpoint. You'll see an Endpoint field there too. For most resources this will be the global endpoint (https://api.cognitive.microsofttranslator.com), which works fine for text translation as long as you pass the region header. However, if your resource was created with a custom domain or if you're using the 2025-10-01-preview API version, you may have a region-specific endpoint that looks like:
https://eastus.api.cognitive.microsofttranslator.com/
These two endpoint formats are not interchangeable in all scenarios. The preview API (api-version=2025-10-01-preview) requires you to use the region-specific endpoint format. If you're getting 404 Not Found responses on the preview API, this is almost certainly why.
For document translation specifically, your endpoint must use the custom subdomain format:
https://YOUR-RESOURCE-NAME.cognitiveservices.azure.com/
The global text translation endpoint will return a 400 for document translation calls. These two endpoint formats serve different features, and mixing them up is one of the most common Azure AI Translator setup errors I've ever seen. Once you fix the endpoint, you should see successful HTTP 200 responses almost immediately.
Asynchronous document translation, the kind that handles batch jobs and complex files while preserving original formatting, requires an Azure Blob Storage account. This is where most enterprise setups break down. The Translator service needs to read your source documents from one blob container and write translated output to another. You have two ways to grant that access: SAS tokens or managed identities.
If you're using SAS tokens, generate them from the Azure Portal by navigating to your Storage Account → Containers → select your container → Generate SAS. Set the permissions to Read for your source container and Read + Write + Create for your target container. Set an expiry time that covers your longest expected job, I'd recommend at least 24 hours for large batch jobs. A common mistake: generating a SAS token at the storage account level instead of the container level. Container-level SAS tokens are more scoped and more reliable for Translator jobs.
If you prefer managed identities (the better long-term option), assign your Translator resource's system-assigned managed identity the Storage Blob Data Contributor role on the storage account. Do this through Storage Account → Access Control (IAM) → Add role assignment. After saving, wait 2-3 minutes for the role to propagate before retrying.
# Check managed identity role assignment via Azure CLI
az role assignment list \
--assignee YOUR_TRANSLATOR_PRINCIPAL_ID \
--scope /subscriptions/SUB_ID/resourceGroups/RG_NAME/providers/Microsoft.Storage/storageAccounts/STORAGE_NAME
If that command returns an empty array, the role isn't assigned. That's your fix right there.
Azure AI Translator uses BCP-47 language tags, and getting them wrong produces 400 Bad Request errors with messages like "The target language is not valid" or "Language not supported." These messages are accurate but not specific enough to tell you what you actually typed wrong.
Common mistakes I see constantly:
- Using
zhinstead ofzh-Hans(Simplified Chinese) orzh-Hant(Traditional Chinese) - Using
ptinstead ofpt-pt(European Portuguese) orpt-br(Brazilian Portuguese) - Using
srwithout specifying script: needs to besr-Cyrlorsr-Latn - Sending uppercase codes like
FRinstead offr
The fastest way to verify a language code is to call the Languages endpoint, which requires no authentication:
GET https://api.cognitive.microsofttranslator.com/languages?api-version=3.0&scope=translation
This returns a JSON object with every valid translation language code. Search for your target language in that response before hardcoding anything in your application.
For character encoding, make sure you're sending Content-Type: application/json; charset=UTF-8 in your request header. If you're translating text that contains Arabic, Hebrew, CJK characters, or any right-to-left script, and your source text gets garbled before it even reaches the API, the encoding is almost always the issue. In Python, explicitly encode strings with .encode('utf-8') before serializing to JSON. In .NET, ensure your StringContent specifies Encoding.UTF8.
Custom Translator lets you build domain-specific translation models, hugely valuable for legal, medical, or technical content where standard neural machine translation (NMT) produces off-brand terminology. But the workflow has several steps where things go wrong silently.
Start in the Custom Translator portal (customtranslator.azure.com). The most common setup error is uploading training documents in the wrong format. Your parallel training data must be in tab-separated UTF-8 TXT files or TMX format. If you upload a Word document or a PDF directly as training data, the portal will appear to accept it but the training job will fail or produce a degraded model.
After training completes, you need to explicitly publish the model to a deployment region before you can call it via the API. Training a model and publishing it are two separate steps, I can't count how many times I've seen developers try to call a trained-but-unpublished model and wonder why they're getting generic NMT output instead of their custom translations.
To call your published custom model, add the category parameter to your text translation request:
POST https://api.cognitive.microsofttranslator.com/translate?api-version=3.0&to=de&category=YOUR_CATEGORY_ID
Ocp-Apim-Subscription-Key: YOUR_KEY
Ocp-Apim-Subscription-Region: eastus
Content-Type: application/json; charset=UTF-8
[{"Text": "The dosage is 500mg twice daily."}]
Your category ID is visible in the Custom Translator portal under Model Details. If you omit it or use the wrong one, you silently get generic NMT output with no error, which is especially annoying to debug. When the call works correctly with your custom model, the response will include "model": {"kind": "CustomTranslator"} in the JSON.
If your application suddenly starts returning 429 Too Many Requests, you've hit Azure AI Translator's service and request limits. This isn't a bug, it's the service enforcing the quotas tied to your pricing tier. But how you handle it matters a lot.
The 429 response will include a Retry-After header that tells you exactly how many seconds to wait before retrying. A huge number of developers ignore this header and implement a fixed 1-second sleep in their retry loop, which is usually either too short (causing more 429s) or too long (causing unnecessary delay). Read the header. Use that value.
For text translation, the standard quota limits are based on characters per second and characters per hour. If you're doing bulk translation of large datasets, batch your requests properly, each API call can include up to 100 translation items in a single JSON array, and each item can be up to 50,000 characters. Sending one item per request when you could send 100 is a fast way to hit rate limits.
# Correct: batch multiple translation items in one request
[
{"Text": "First sentence to translate."},
{"Text": "Second sentence to translate."},
{"Text": "Third sentence to translate."}
]
For asynchronous document translation jobs, check the job status endpoint rather than polling on a fixed interval. Use exponential backoff, start at 5 seconds, double each time, cap at 60 seconds. Document translation jobs for large files can run for 10-30 minutes, and constant polling wastes your API quota and can trigger additional rate limiting.
If you legitimately need higher throughput than your current tier allows, go to Azure Portal → Your Translator Resource → Pricing tier and upgrade. The S1 tier supports significantly higher character limits than F0 (free). Check the official Azure Translator pricing page for current numbers, as limits do change with service updates.
Advanced Troubleshooting
Diagnosing Failures with Azure Monitor and Diagnostic Logs
When you're stuck on an intermittent error that you can't reproduce on demand, Azure Monitor is your best friend. In the Azure Portal, navigate to your Translator resource and select Diagnostic settings under the Monitoring section. Add a diagnostic setting that sends logs to a Log Analytics workspace. Enable the RequestResponse log category.
Once logs are flowing, you can query them in Log Analytics with KQL:
AzureDiagnostics
| where ResourceType == "ACCOUNTS" and Category == "RequestResponse"
| where ResultSignature != "200"
| project TimeGenerated, ResultSignature, DurationMs, OperationName, CallerIPAddress
| order by TimeGenerated desc
| take 50
This surfaces every failed request with its HTTP status code, duration, and caller IP. If you're seeing 401 errors only from specific IP addresses, that points to a network configuration or key management issue scoped to certain environments. If all 401s come right after a scheduled task runs, your key rotation automation is probably regenerating both keys simultaneously instead of rotating them.
Network-Level Issues: Firewalls and Private Endpoints
If your Translator resource is configured with a network access restriction (under Networking in the resource settings), requests from outside the allowed IP ranges will return 403 without any explanation. Check Networking → Firewalls and virtual networks and confirm your application server's outbound IP is in the allowed list.
For enterprise environments using Azure Private Endpoints with Translator, the DNS resolution must route correctly. If you've set up a private endpoint but haven't configured the corresponding Private DNS Zone (privatelink.cognitiveservices.azure.com), your internal clients will resolve the public IP instead of the private one and fail if public access is disabled. Run:
nslookup YOUR-RESOURCE-NAME.cognitiveservices.azure.com
If it resolves to a 10.x.x.x or 172.x.x.x address, your private DNS is working. If it resolves to a public Azure IP, your DNS zone linkage is broken.
Migrating from API v3 to the 2025-10-01-preview
The preview API introduced LLM-based translation options (GPT-4o, GPT-4o mini) alongside the standard NMT engine. The request schema changed: you now pass a textType parameter and optionally a model parameter. If you upgraded your api-version query string without updating your request body, you'll get 400 errors. Read the preview migration guide in the official Foundry Tools documentation before touching the API version string in production.
Prevention & Best Practices
Most Azure AI Translator outages I've seen are self-inflicted. They come from hardcoded keys, no retry logic, skipped documentation on new API versions, and storage accounts set up with default permissions that break the moment someone tightens security. Here's how to stay out of trouble.
Store your API keys in Azure Key Vault and reference them through environment variables or managed identity authentication, never hardcode them in source files. Rotate keys on a schedule (monthly is fine for most workloads) using the two-key rotation pattern: switch to KEY 2, regenerate KEY 1, wait 60 seconds, switch back to KEY 1, regenerate KEY 2. This keeps your service running with zero interruption.
Adopt managed identities over SAS tokens wherever possible for document translation. SAS tokens expire, get accidentally committed to git repositories, and create audit trail gaps. Managed identities tied to your Translator resource with RBAC roles on your storage account are easier to revoke, easier to audit, and impossible to accidentally expose in code.
When you update your API version, especially to a preview version like 2025-10-01-preview, test in a staging environment first. The preview API introduced breaking changes to the request body format. What worked on 3.0 may not work on the preview without modifications. Treat preview API version changes like minor version bumps in any library: read the migration guide, test everything, then promote to production.
For teams using Custom Translator, document your category IDs in a shared configuration file or Key Vault secret. When someone rebuilds or republishes a custom model, the category ID changes. If that ID is scattered across multiple services and apps as a hardcoded string, a model republish silently breaks translation quality everywhere, and it's a nightmare to track down.
- Set up Azure Monitor alerts on your Translator resource for error rate above 1%, catch problems before users do
- Call the
/languagesendpoint at startup to validate language codes dynamically instead of hardcoding them - For document translation, always name your Blob Storage containers with all-lowercase letters and hyphens only, uppercase characters cause silent job failures
- Test the Microsoft Foundry playground after any resource configuration change to confirm the service is healthy before deploying code changes
Frequently Asked Questions
What is Azure AI Translator and what does it actually do?
Azure AI Translator (officially Azure Translator in Foundry Tools) is a cloud-based neural machine translation service that translates text and documents between more than 100 languages via a REST API. It covers three main scenarios: real-time text translation, document translation (both single-file synchronous and large-batch asynchronous), and Custom Translator for domain-specific models. It powers many Microsoft products and services, and as of November 2025, it also supports LLM-based translation through GPT-4o and GPT-4o mini models via the Microsoft Foundry portal. You can try it for free with an Azure free account before committing to a paid tier.
Why do I keep getting 401 Unauthorized even though my API key looks right?
The most likely culprit is a missing or incorrect Ocp-Apim-Subscription-Region request header. This header is required for single-service Translator resources, omitting it produces a 401 even with a valid key. Get the exact region string from your resource's Overview page in the Azure Portal (it looks like eastus or westeurope) and include it verbatim in every request. Also check that you haven't accidentally added a trailing space when copying the key, that's embarrassingly common and produces the exact same error.
How do I set up document translation with Azure Blob Storage?
Asynchronous document translation requires an Azure Blob Storage account with at least two containers: one for source documents and one for translated output. You authorize the Translator service to access these containers using either SAS tokens (generated per container with appropriate read/write permissions) or a managed identity with the Storage Blob Data Contributor role. The API endpoint for document translation must use your resource's custom subdomain format (https://YOUR-RESOURCE-NAME.cognitiveservices.azure.com/), not the global text translation endpoint. Name your containers with lowercase letters and hyphens only to avoid silent job failures.
What's the difference between Azure Translator API v3 and the 2025-10-01-preview?
The 2025-10-01-preview API version is the newest release of Azure Translator in Foundry Tools and introduces two major additions that aren't in the stable v3: the ability to select specific large language models (including GPT-4o and GPT-4o mini) for individual translation requests, and adaptive custom translation. The preview API uses a different request body schema and requires a region-specific endpoint URL rather than the global endpoint. Microsoft released a preview migration guide covering the breaking changes, read it before updating your api-version parameter in any production code.
How do I use a Custom Translator model in my API calls?
After training and publishing your custom model in the Custom Translator portal (publishing is a separate step from training), add the category query parameter to your text translation API request with the value of your model's category ID. The category ID is shown in the Model Details section of the Custom Translator portal. Without this parameter, the API silently falls back to standard neural machine translation and returns no error, which makes it easy to miss if you're not checking the response metadata. The response from a successful custom model call will include "model": {"kind": "CustomTranslator"} in the JSON body, confirming your custom model was used.
What's new in Azure Translator as of early 2026, should I update my integration?
The biggest changes in late 2025 are the launch of the Microsoft Foundry portal (November 2025), which gives you a no-code interface for text and synchronous document translation, and the 2025-10-01-preview API that lets you pick between standard NMT, GPT-4o, and GPT-4o mini at the request level. Microsoft Translator Pro also expanded its on-device language support for offline mobile translation. If your integration uses the stable v3 API and you're happy with NMT quality, you don't need to migrate immediately. But if you need gender-aware or tone-aware translations, which the new Foundry LLM options support, the preview API is worth exploring in a test environment.