What Is Status Code: 406 Not Acceptable? The Picky Eater Protocol

What is HTTP 406 Not Acceptable? This guide explains this content negotiation error code, how Accept headers work, and how to fix compatibility issues between clients and servers.

INEZA Felin-Michel

INEZA Felin-Michel

30 September 2025

What Is Status Code: 406 Not Acceptable? The Picky Eater Protocol

In the rich vocabulary of HTTP status codes, some codes stand out more than others while some quietly perform vital roles in ensuring smooth client-server communications. The 406 Not Acceptable status code is one such lesser-known hero. It might not appear as frequently as the popular 404 or 500, but understanding its purpose can dramatically improve your grasp of content negotiation and enhance the flexibility of your web applications and APIs.

The 406 Not Acceptable status code can feel like a cryptic message from your server. But once you understand what it means, it becomes a powerful signal that helps you design cleaner, more predictable, and more user-friendly APIs.

This status code represents a communication breakdown in the sophisticated dance of content negotiation process where clients and servers agree on the best format for data exchange.

In this blog post, we'll take a deep dive into what HTTP 406 Not Acceptable means, why it happens, how content negotiation influences it, and how you, as a developer or API consumer can deal with it effectively. Debugging weird errors like 406 Not Acceptable can be time-consuming without the right tools. That's why I recommend Apidog. It's a free, all-in-one API platform that lets you design, mock, test, debug and document APIs with ease so you'll know exactly why you're getting a 406 and how to fix it fast.

💡
If you want to explore and test APIs seamlessly including responses with 406 status, download Apidog for free. Apidog is an essential API testing and documentation tool that makes investigating HTTP status codes like 406 easy and effective.
button

Now, let's explore the world of content negotiation and the HTTP 406 Not Acceptable status code.

The Problem: Everyone Wants Data Their Own Way

In the early days of the web, servers typically offered one format for their resources usually HTML. But as the web evolved, different clients emerged with different needs:

The 406 status code exists because sometimes a client asks for a format that the server simply cannot provide for that particular resource.

What Does HTTP 406 Not Acceptable Actually Mean?

The 406 Not Acceptable status code indicates that the server cannot produce a response matching the list of acceptable values defined in the request's proactive content negotiation headers, and that the server is unwilling to supply a default representation.

In simpler terms: "You've told me exactly what formats you'll accept, and I can't provide the resource in any of those formats."

A proper 406 response should include information about what formats the server can provide for the requested resource. This is typically done with headers or in the response body.

Here's what a 406 response might look like:

HTTP/1.1 406 Not AcceptableContent-Type: text/htmlVary: Accept
<html><head><title>406 Not Acceptable</title></head><body><h1>Not Acceptable</h1><p>This resource is available in the following formats:</p><ul><li>application/json</li><li>application/xml</li></ul></body></html>

For APIs, it's more helpful to return a structured response:

HTTP/1.1 406 Not AcceptableContent-Type: application/jsonVary: Accept
{
  "error": "not_acceptable",
  "message": "The requested resource is not available in the requested format.",
  "available_formats": [
    "application/json",
    "application/xml"
  ]
}

It's not about whether the request is valid. It's about whether the response type is acceptable.

The Magic of Content Negotiation: How Accept Headers Work

To understand 406, we need to understand how clients tell servers what formats they prefer. This happens through the Accept header.

The Accept Header in Action

When a client makes a request, it can specify what content types it can handle and which ones it prefers:

A simple example:

GET /api/users/123 HTTP/1.1Accept: application/json

This says: "I want user data, and I only understand JSON."

A more sophisticated example:

GET /api/users/123 HTTP/1.1Accept: application/json, text/html;q=0.9, application/xml;q=0.8

This says: "I prefer JSON, but I can also handle HTML (with 90% preference) and XML (with 80% preference)."

The q parameter (quality value) ranges from 0 to 1, with 1 being the most preferred.

When Negotiation Fails

A 406 error occurs when the server looks at the Accept header and realizes:

  1. It has the resource the client wants
  2. It cannot provide it in any of the formats the client specified
  3. It's not willing to send a default format (like sending JSON to a client that only accepts XML)

How Does 406 Not Acceptable Fit Into Content Negotiation?

When a client sends an HTTP request including Accept headers specifying acceptable media types (e.g., requesting JSON responses only), the server will attempt to deliver content accordingly.

If the server cannot provide any acceptable content that fits the criteria, it responds with:

textHTTP/1.1 406 Not Acceptable Content-Type: text/html

At this point, it means the server rejects the request because none of the available content representations match the client’s preferences.

Why Servers Return 406 Instead of 200 OK

You might think: why not just return something, even if it's not the preferred format?

Here's why servers return 406:

Common Causes of a 406 Response

Here are some typical reasons you'll see 406 Not Acceptable:

Real-World Scenarios That Trigger 406 Errors

1. API Versioning Conflicts

Imagine an API that only serves JSON in its v2, but a client still expects XML from the v1 days:

GET /v2/products/456 HTTP/1.1Accept: application/xmlHTTP/1.1 406 Not AcceptableContent-Type: application/json
{
  "error": "This API version only supports JSON",
  "available_formats": ["application/json"]
}

2. Overly Restrictive Client Configuration

A mobile app might be hardcoded to only accept JSON, but encounters a server that only serves certain resources as XML:

GET /reports/quarterly-sales HTTP/1.1Accept: application/jsonHTTP/1.1 406 Not Acceptable

(The report might only be available as CSV or PDF)

3. Missing Default Fallback

Some servers are configured to be strict about content negotiation and refuse to guess what format to return when negotiation fails.

How Do Servers Usually Handle 406?

Interestingly, some servers ignore strict content negotiation and fallback to a default response rather than responding with 406.

However, strict RESTful APIs or services that emphasize precise communication might return 406 when client requirements cannot be met.

To clarify 406's role, let's look at related HTTP statuses:

Status Code Meaning When to Use
400 Bad Request Malformed syntax or invalid request Request can’t be understood
406 Not Acceptable Valid request but server can’t fulfill accept headers Content negotiation failure
415 Unsupported Media Type Server can’t process content type submitted by client Invalid request body media
406 vs 415 difference 406 relates to response type, 415 relates to request body type

How Should Clients Handle 406 Responses?

Clients receiving 406 should:

What Can Developers Do to Avoid or Handle 406?

Custom 406 Error Pages and Messages

For websites and APIs, serving meaningful and helpful 406 error responses improves the developer and user experience:

Testing Content Negotiation with Apidog

Testing how your API handles different Accept headers is crucial for building robust applications. Apidog makes this process straightforward and efficient.

With Apidog, you can:

  1. Easily Modify Headers: Quickly add and modify Accept headers to test how your server responds to different content type requests.
  2. Test Multiple Formats: Create a collection of tests for the same endpoint with different Accept headers (JSON, XML, HTML) to ensure comprehensive coverage.
  3. Validate 406 Responses: Intentionally send restrictive Accept headers to verify that your server returns proper 406 responses with helpful error information.
  4. Automate Content Negotiation Tests: Create test suites that automatically verify your API correctly handles various content type requests and returns appropriate status codes.
  5. Debug Complex Scenarios: Use Apidog's detailed logging to understand exactly why a 406 error occurred and what formats the server actually supports.
button

This systematic approach ensures your API can gracefully handle clients with different format requirements. In short: instead of fumbling in the dark, you know exactly what's acceptable. Download Apidog for free and boost your productivity in troubleshooting content negotiation and 406 scenarios.

Best Practices for Handling 406 Errors

For Server Developers:

  1. Provide Helpful Error Information: When returning a 406, always include information about what formats you do support. This helps client developers fix their requests.
  2. Use the Vary Header: Include a Vary: Accept header in your responses to indicate that the response content varies based on the Accept header. This helps caching systems work correctly.
  3. Consider Default Behavior: While the HTTP spec allows servers to return a default representation, many modern APIs choose to be strict and return 406 to force clients to be explicit about their requirements.
  4. Document Supported Formats: Clearly document what content types your API supports for each endpoint.

For Client Developers:

  1. Be Flexible in Accept Headers: Unless you have a specific reason, include multiple formats in your Accept header with appropriate quality values.
  2. Handle 406 Gracefully: When you receive a 406, check the response for available formats and either adjust your request or show a helpful error message to the user.
  3. Have Fallback Logic: Consider having fallback logic that can handle different formats if your primary preferred format isn't available.

The Unsung Hero of Content Negotiation

The Vary header is crucial for proper caching behavior when content negotiation is involved. When a server includes Vary: Accept in its response, it tells caches that the response content depends on the Accept header value.

This prevents a cache from incorrectly serving a JSON response to a client that requested XML, or vice versa.

Impact on SEO of 406 Responses

Generally, 406 does not affect SEO significantly because search engines usually handle content negotiation robustly and prefer valid responses. However, misconfigured APIs or websites that frequently return 406 can frustrate crawlers or users.

Modern API Design and 406

In modern RESTful API design, the use of 406 has evolved:

However, 406 remains relevant for:

Troubleshooting 406 Errors

Security Considerations Around 406

Conclusion: Embracing HTTP 406 Not Acceptable for Precise Communication

The HTTP 406 Not Acceptable status code represents an important principle of web architecture: clear communication between clients and servers about their capabilities and requirements. It's not an error to be feared, but a mechanism for ensuring that data exchange happens in mutually understandable formats.

While you might not encounter 406 daily, understanding it makes you a better web citizen. It teaches the importance of being explicit about data format requirements and handling format negotiation gracefully.

For API developers, properly implementing content negotiation and 406 responses leads to more robust and flexible APIs. For client developers, understanding how to work with 406 errors ensures your applications can adapt to different server capabilities.

In a world where data needs to flow between diverse systems and platforms, the ability to negotiate content format is more valuable than ever. And when you need to test and perfect these negotiations, a tool like Apidog provides the perfect environment to ensure your applications communicate effectively, regardless of format preferences.

button

Explore more

How to use Claude Sonnet 4.5 in Claude Code

How to use Claude Sonnet 4.5 in Claude Code

Dive into this conversational guide on claude code with claude sonnet 4.5! Explore benchmarks, claude code v2.0 updates, and a full step-by-step to integrate Sonnet 4.5 for agents and tasks. Plus, quick pricing ($3/M input) and why it's a dev must-have.

30 September 2025

What Is Status Code: 407 Proxy Authentication Required? The Gatekeeper's Gatekeeper

What Is Status Code: 407 Proxy Authentication Required? The Gatekeeper's Gatekeeper

Discover what the 407 Proxy Authentication Required HTTP status code means, why it happens, and how to fix it. Learn common causes and how Apidog helps developers handle proxy errors with ease.

30 September 2025

Three Working Methods to Use Claude Sonnet 4.5 for Free

Three Working Methods to Use Claude Sonnet 4.5 for Free

Discover practical methods to use Claude Sonnet 4.5 for free in 2025—including partner access, Puter.js, and smart workflows—plus how Apidog turns AI speed into shipped, documented APIs.

30 September 2025

Practice API Design-first in Apidog

Discover an easier way to build and use APIs