Website Vidya
DeploymentStep-by-Step Guide

How to Fix 405 Method Not Allowed: Easy Steps

The 405 Method Not Allowed error is a common HTTP status code that can be frustrating for both users and developers. When you encounter this message, it means the web server recognizes your request but has rejected the specific HTTP method ...

RR
Website Vidya TeamLead Systems Educator
Published:
10 min read
How to Fix 405 Method Not Allowed: Easy Steps
AI Executive SummaryCORE CIS AI

10 min read

The 405 Method Not Allowed error is a common HTTP status code that can be frustrating for both users and developers. When you encounter this message, it means the web server recognizes your request but has rejected the specific HTTP method ...

Key Highlights
  • What is the 406 Not Acceptable Error?
  • How Content Negotiation Triggers 406 Errors
  • Step-by-Step: How to Fix 406 Not Acceptable Error
Grounded in full engineering runbookCORE CIS Ai Engine

What is the 406 Not Acceptable Error?

The 406 Not Acceptable is an HTTP client error status code that indicates the server cannot produce a response matching the list of acceptable values defined in the request's proactive content negotiation headers. Unlike server errors (5xx) or client errors like 404 (Not Found), 406 Not Acceptable specifically addresses a mismatch between what the client asks for and what the server can actually deliver.

When you encounter a 406 Not Acceptable Error, it means your browser or application has requested content with specific requirements (format, encoding, or language) that the server cannot satisfy with its available resources. In this article, we will understand how to fix 406 Not Acceptable Error.

How Content Negotiation Triggers 406 Errors

Proactive content negotiation happens through specific HTTP headers. The three main headers involved are:

  1. Accept: Specifies preferred media types (like application/json, text/html)
  2. Accept-Encoding: Defines acceptable content encodings (like gzip, br)
  3. Accept-Language: Indicates preferred languages (like en-US, fr-FR)

Real-World Example: Why 406 Happens

Consider this API request:

GET /api/users/123 HTTP/1.1
Host: api.example.com
Accept: application/xml

If the server only supports JSON responses, it should return:

HTTP/1.1 406 Not Acceptable
Content-Type: application/json

{
  "error": "Unsupported media type",
  "available_formats": ["application/json"],
  "message": "This endpoint only supports JSON responses"
}

Step-by-Step: How to Fix 406 Not Acceptable Error

Solution 1: Adjust Client Request Headers (Most Common Fix)

The most common fix for 406 Not Acceptable involves examining the Accept headers sent by your client:

  • Browser Requests: Most browsers automatically send Accept headers. You can use browser developer tools (F12 → Network tab) to examine what headers are being sent.
  • API Clients: If you're using tools like Postman, cURL, or custom code, explicitly set Accept headers to match what the server can provide.
  • Adjust Headers: Try changing the Accept header to a more generic value like */* or to specifically match the server's capabilities.

For API Consumers and Developers:

If you're making API calls and receiving 406 Not Acceptable, modify your Accept headers:

// Before: Requesting XML when server only has JSON
fetch('https://api.example.com/data', {
  headers: {
    'Accept': 'application/xml' // Causes 406 if server doesn't support XML
  }
});

// After: Requesting JSON or using wildcard
fetch('https://api.example.com/data', {
  headers: {
    'Accept': 'application/json' // Specific type server supports
  }
});

// OR use wildcard to accept anything
fetch('https://api.example.com/data', {
  headers: {
    'Accept': '*/*' // Accept any response type
  }
});

For Browser Issues:

  1. Open Developer Tools (F12)
  2. Go to Network tab
  3. Reload the page
  4. Check the request headers being sent
  5. Use browser extensions to modify headers if needed

Solution 2: Server-Side Configuration for Web Administrators

If you control the server, consider these adjustments to resolve 406 Not Acceptable:

  • Configure Content Negotiation: Ensure your web server (Apache, Nginx, IIS) is properly configured to handle the content types your clients are requesting.
  • Check MIME Type Settings: Verify that your server has the correct MIME types configured for the files or responses being served.
  • Review Application Settings: For applications like WordPress, check plugin conflicts or theme issues that might be affecting content negotiation.

If you control the server, implement proper content negotiation:

Apache (.htaccess):

# Ensure proper MIME types
AddType application/json .json
AddType text/html .html

# Handle Accept header negotiation
<IfModule mod_negotiation.c>
  # Set default to HTML if no Accept header matches
  Options +MultiViews
  ForceType text/html
</IfModule>

Nginx Configuration:

location /api/ {
    # Default to JSON if Accept header doesn't match
    if ($http_accept ~* "application/json") {
        add_header Content-Type application/json;
    }

    # Return 406 only for truly unsupported types
    if ($http_accept !~* "(application/json|text/html|\*/\*)") {
        return 406;
    }

    # Default response type
    default_type application/json;
}

Solution 3: Framework-Specific Implementations

Each web framework handles content negotiation differently. Configure your server-side framework to properly validate Accept headers and provide appropriate fallbacks or detailed 406 responses when clients request unsupported formats. The key is implementing robust content negotiation logic that either satisfies the request or clearly communicates available alternatives.

Express.js Example:

const express = require('express');
const app = express();

// Middleware to handle content negotiation
app.use((req, res, next) => {
  const acceptHeader = req.get('Accept') || '*/*';

  // Check if we support requested type
  const supportedTypes = ['application/json', 'text/html'];
  const acceptedTypes = acceptHeader.split(',').map(t => t.trim());

  const canServe = acceptedTypes.some(type => 
    supportedTypes.includes(type) || type === '*/*'
  );

  if (!canServe && acceptHeader !== '*/*') {
    return res.status(406).json({
      error: 'Not Acceptable',
      message: 'Supported content types: application/json, text/html',
      acceptHeader: acceptHeader
    });
  }

  next();
});

app.get('/api/data', (req, res) => {
  const accept = req.get('Accept');

  if (accept.includes('text/html')) {
    res.send('<html><body>Data: example</body></html>');
  } else {
    res.json({ data: 'example' });
  }
});

Django REST Framework:

# settings.py
REST_FRAMEWORK = {
    'DEFAULT_RENDERER_CLASSES': [
        'rest_framework.renderers.JSONRenderer',
        'rest_framework.renderers.BrowsableAPIRenderer',  # HTML for browser
    ],
    'DEFAULT_CONTENT_NEGOTIATION_CLASS': 
        'rest_framework.negotiation.DefaultContentNegotiation',
}

# views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

class UserView(APIView):
    def get(self, request):
        # Check Accept header
        accepted = request.META.get('HTTP_ACCEPT', '*/*')

        if 'application/xml' in accepted and 'application/json' not in accepted:
            return Response(
                {'error': 'XML not supported. Use application/json'},
                status=status.HTTP_406_NOT_ACCEPTABLE
            )

        return Response({'user': 'data'})

Solution 4: Fix ModSecurity False Positives

ModSecurity and other web application firewalls often trigger 406 Not Acceptable errors:

  • Temporarily Disable ModSecurity: To test if this is the cause, temporarily disable ModSecurity rules.
  • Review Security Logs: Check ModSecurity audit logs for specific rules that might be blocking the request.
  • Whitelist Accept Headers: Adjust your security rules to allow the Accept headers your legitimate clients are using.

ModSecurity rules often trigger 406 Not Acceptable Error. To diagnose:

  1. Check ModSecurity logs:
# Apache
tail -f /var/log/apache2/modsec_audit.log

# Look for rules like 959100, 959010 which block certain Accept headers
  1. Temporarily disable to test:
# In .htaccess or virtual host
<IfModule mod_security2.c>
  SecRuleRemoveById 959100
  SecRuleRemoveById 959010
</IfModule>
  1. Whitelist legitimate Accept headers:
SecRule REQUEST_HEADERS:Accept "@rx ^(application/json|text/html|\*/\*|application/xml)" \
    "id:1001,phase:1,pass,nolog,ctl:ruleRemoveById=959100"

Solution 5: Implement Proper Error Responses

When your server must return a 406 Not Acceptable Error, don't just send a generic status code. Transform this error into a helpful conversation by providing detailed, actionable responses that guide clients toward available alternatives. Well-crafted 406 responses should serve as a roadmap, not a dead end—clearly explaining what went wrong, what content types you do support, and how clients can successfully retrieve the resource they need.

When returning 406 Not Acceptable, provide helpful information:

# Python Flask example
from flask import Flask, jsonify, request

app = Flask(__name__)

@app.route('/data')
def get_data():
    supported = ['application/json', 'text/plain']
    accept = request.headers.get('Accept', '*/*')

    # Check if we can satisfy the request
    if not any(media_type in accept for media_type in supported) and accept != '*/*':
        return jsonify({
            "error": "406 Not Acceptable",
            "message": "Cannot satisfy Accept header requirements",
            "requested": accept,
            "supported": supported,
            "suggestion": "Try Accept: application/json"
        }), 406, {'Content-Type': 'application/json'}

    # Normal response handling...

Testing and Debugging Strategies

Using cURL for Diagnosis

# Test different Accept headers
curl -H "Accept: application/xml" https://api.example.com/data
# Returns 406

curl -H "Accept: application/json" https://api.example.com/data
# Returns 200 with JSON

curl -H "Accept: */*" https://api.example.com/data
# Returns 200 with server's default

# Verbose output to see headers
curl -v -H "Accept: application/rtf" https://api.example.com/docs/doc1

Browser Developer Tools Approach

  1. Open Network tab in DevTools
  2. Find the failing request
  3. Right-click → Copy → Copy as cURL
  4. Modify the Accept header in the copied command
  5. Test in terminal to isolate the issue

Best Practices to Prevent 406 Errors

Client-Side:

  • Always specify fallback Accept headers: Accept: application/json, text/html, */*
  • Implement retry logic with different Accept headers
  • Parse server's 406 response for supported types

Server-Side:

  • Implement graceful fallbacks to default representations
  • Provide detailed error messages in 406 responses
  • Support common Accept header patterns
  • Document supported media types in API documentation

API Design:

   # Good: Server returns helpful 406 response
   HTTP/1.1 406 Not Acceptable
   Content-Type: application/json

   {
     "error": "unsupported_media_type",
     "message": "Requested 'application/rtf' not available",
     "supported_types": [
       "text/html",
       "application/json",
       "application/pdf"
     ],
     "links": {
       "html": "/docs/doc1.html",
       "json": "/api/docs/doc1",
       "pdf": "/docs/doc1.pdf"
     }
   }

When 406 Should (and Shouldn't) Be Used

Use 406 when:

  • You have multiple representations available
  • The client explicitly requests an unsupported format
  • You want to guide the client to available options

Consider alternatives:

  • 200 OK with default representation: When you have a reasonable default
  • 300 Multiple Choices: When you want to redirect to available options
  • 415 Unsupported Media Type: For request body format issues (not Accept header)

Conclusion: 406 Not Acceptable Error

Understanding and fixing 406 Not Acceptable Error requires attention to the HTTP content negotiation process. Whether you're a client developer adjusting request headers or a server administrator configuring proper response handling, the key is ensuring alignment between client expectations and server capabilities.

By implementing the solutions outlined in this guide on how to fix 406 Not Acceptable Error, you can transform a frustrating error into a helpful dialogue between client and server, ultimately creating more robust and user-friendly web applications and APIs.

Remember: The 406 Not Acceptable response, when implemented properly, isn't just an error—it's an opportunity to communicate clearly with clients about what you can provide and guide them toward successful interactions with your server.

For more technical details and official specifications about the 406 Not Acceptable Error, refer to the MDN Web Docs HTTP 406 documentation.


Written by

Website Vidya Team

Technology educator and researcher at Website Vidya.

Discussion

0
Share your thoughts, ask a question, or suggest a tip...
Write →

No comments on this guide yet. Be the first to share your thoughts or ask a question!

Recommended Reading10 Guides

Related Technical Guides

Tested runbooks, server administration walkthroughs, and troubleshooting guides

Deployment•

How to Install PDO Extension in PHP

PHP Data Objects (PDO) is one of the most important extensions in PHP for working with databases in a secure, consistent, and modern way. If you are building dynamic websites, APIs, CMS platforms, or enterprise applications, PDO is not opti...

RR
Rajesh Rai
Read More
Deployment•

25 Best Linux Commands Every Sysadmin Should Know

If you’ve spent any time managing Linux servers, you already know this truth: the command line is not optional. It’s where real troubleshooting happens, where performance issues are understood, and where outages are prevented before users e...

RR
Rajesh Rai
Read More
Deployment•

How to Fix Snapd Consuming High CPU / RAM on Linux

If you’ve ever opened your system monitor and noticed snapd quietly eating up your CPU or RAM, you’re not alone. Many Linux users—especially on Ubuntu and Ubuntu-based distributions—eventually run into this issue and wonder what’s going on ...

RR
Rajesh Rai
Read More