HTTP 406: alles wat je moet weten over Not Acceptable en hoe je het oplost

Wanneer een webserver of API een HTTP 406-status teruggeeft, spreken we van een Not Acceptable toestand. Het klinkt technisch, maar achter HTTP 406 schuilen concrete keuzes over wat een client en server wel of niet kunnen uitwisselen. In dit artikel duiken we diep in HTTP 406, leggen we uit waarom het voorkomt, wat de effecten zijn op gebruikerservaring en tooling, en geven we praktische stappen en best practices om deze fout efficiënt op te lossen. We behandelen zowel server- als clientkant, verschillende implementaties en concrete configuratievoorbeelden.
HTTP 406: wat betekent HTTP 406 en waarom bestaat het?
HTTP 406, voluit Not Acceptable, is een statuscode uit het HTTP-protocol die aangeeft dat de server geen representatie kan leveren die voldoet aan de voorwaarden die de client heeft gesteld via de Accept-header of andere content-negotiation-mechanismen. In eenvoudige bewoordingen: de client vraagt om een bepaald type data, formaat of taal via accept-voorwaarden, maar de server kan geen aanbod doen waar aan die voorwaarden wordt voldaan.
HTTP 406: de rol van content negotiation
Content negotiation is het proces waarbij client en server afspraken maken over de vorm van de antwoordinhoud. Denk aan:
- Inhoudstype (MIME-type), bijvoorbeeld text/html, application/json, image/png
- Taalversie van de content
- Codering of compressie-formaat
- Kleur- of formaatvarianten van media
Wanneer geen enkel aanbod voldoet aan de Accept-header of aan combinatie van Accept-, Accept-Language-, Accept-Encoding- en andere relevante headers, kan HTTP 406 Not Acceptable respons teruggegeven worden. Dat is precies waar HTTP 406 in het spel komt: de server kan niet leveren wat de client volgens de afgesproken onderhandelingen verwacht.
Wanneer krijg je HTTP 406 vaak te zien?
HTTP 406 komt in verschillende scenario’s voor. Hier zijn de meest voorkomende situaties:
Onvervulde Accept-criteria
De client stuurt een Accept-header die zo specifiek is dat de server geen geldige combinatie kan leveren. Bijvoorbeeld Accept: text/html; charset=utf-8 terwijl de server alleen text/html; charset=iso-8859-1 aan kan bieden, of juist een JSON-antwoord verwacht dat niet in de Accept-standaard gecatalogiseerd is.
Onvoldoende ondersteunde compressie of encodering
Accept-Encoding kan beperkt zijn en de server biedt alleen compressie-opties aan die de client niet accepteert, waardoor geen geaccepteerde representatie beschikbaar is.
Meerdere Accept-Language-varianten
Wanneer een API of site content aanbiedt in meerdere talen en de Accept-Language-header zo specifiek is dat er geen overeenkomende taal beschikbaar is, kan HTTP 406 volgen.
Content-negotiation in API-omgevingen
Bij RESTful of GraphQL-achtige API’s kan HTTP 406 optreden als de server geen representatie kan leveren die voldoet aan de gevraagde media-typen of schema’s die de client via de accept-voorwaarden heeft opgegeven.
Veelvoorkomende oorzaken van HTTP 406
Het begrijpen van de oorzaken helpt bij het voorkomen en sneller oplossen van HTTP 406. Hieronder staan de meest voorkomende oorzaken, met toelichting per situatie:
Specifieke Accept-voorwaarden die niet worden ondersteund
Het bericht vraagt om een heel specifiek formaat of encoding dat de server niet ondersteunt. Bijvoorbeeld Accept: application/pdf; qs=0.9 terwijl de server alleen text/html en application/json kan leveren.
Onverwachte content-negotiation-logica
Sommige frameworks hebben ingebouwde logica voor onderhandelingen die onbedoeld strenger zijn dan nodig. Een foutje in middleware of router kan leiden tot HTTP 406 wanneer er eigenlijk wel een alternatief beschikbaar is.
Foutieve configuratie van server-plugins of modules
Plugins die gedrag rond content-negotiation altereren (bijv. Nginx- of Apache-modules, of API-gateways) kunnen per ongeluk de Accept-headers verkeerd interpreteren of beperken.
API-versies en media-types mismatches
Wanneer een API meerdere versies of formaten aanbiedt, maar de client een verouderd/nieuwe variant verzoekt die niet ondersteund wordt door de server, ontstaat HTTP 406.
Een systematische aanpak bespaart veel tijd. Hieronder vind je stappen die zowel op development als productie toepasbaar zijn.
1. Inspecteer de request headers zorgvuldig
Check vooral de Accept-, Accept-Language-, Accept-Encoding-, en eventueel Content-Type headers. Kijk ook naar eventuele custom negotiation headers die door de API worden gebruikt. Noteer welke waarden de client stuurt en waar de server mogelijk geen match kan vinden.
2. Controleer server- en applicatie logs
Zoek naar HTTP 406-regels in de logs en kijk naar de bijbehorende request-payloads, user-agents, en backend-stack. Logs geven vaak verbindingen met specifieke middleware of plugins aan die de onderhandelingen beïnvloeden.
3. Test met permissieve fallbacks
Probeer een bredere Accept-header, bijvoorbeeld Accept: */*, of uitschakelen van bepaalde negotiatie-logica via testomgevingen. Als HTTP 406 verdwijnt bij bredere Accept-voorwaarden, ligt het probleem bij de accept-criteria van de client.
4. Controleer de serverconfiguratie
Bij webservers zoals Nginx, Apache of reverse proxies kan een configuratie de onderhandelingen beperken. Kijk naar configuratieblokken die Accept-Language, Accept-Encoding of specifieke content-types afdwingen.
5. Beoordeel API-gateways en middleware
Middleware kan negotiated content forceren op een manier die niet overeenkomt met de clientverwachtingen. Controleer routes, verwerkingsstapjes en eventuele middleware-voorwaarden die HTTP 406 kunnen triggeren.
6. Maak expliciete fallback-responses
Als een server niet in staat is om aan de gewenste representatie te voldoen, kan het nuttig zijn om een duidelijke 406-antwoord te sturen met een content-negotiation-handleiding. Dit helpt clients sneller correct aan te sturen.
Hieronder vind je voorbeelden van hoe verschillende technologieën met HTTP 406 omgaan. De voorbeelden illustreren hoe je zowel het gedrag kunt onderzoeken als oplossen.
Voorbeeld 1: Nginx – content negotiation beperken of uitschakelen
# Voorbeeld: basic fallback-acceptatie beperken
server {
listen 80;
server_name voorbeeld.be;
location / {
# Standaard content-type, geen speciale negotiatie
add_header Vary Accept;
try_files $uri $uri/ =404;
}
# Optionele restrictie op Accept-headers kan hier gezet worden
}
Bij dit voorbeeld kun je spelen met de Vary-header en het gedrag van try_files om HTTP 406 te voorkomen of om een duidelijke fallback te bieden.
Voorbeeld 2: Apache – Handling van Accept-headers
# Apache-configuratie kan via negotiation-instellingen
Options +Indexes
Negotiation on
Let op: negotiation in Apache kan complex zijn. In sommige gevallen kan het zonder duidelijke fallback leiden tot HTTP 406. Het is vaak beter om explicieter te definiëren welke content-types toegestaan zijn en fallback-opties te voorzien.
Voorbeeld 3: Node.js (Express) – expliciete fallback naar JSON
const express = require('express');
const app = express();
// Middleware: content negotiation vereenvoudigen
app.use((req, res, next) => {
// Sta Accept-headers toe tot application/json of text/html
const acceptsJson = req.accepts(['application/json']);
if (!acceptsJson && req.accepts() !== '*/*') {
return res.status(406).send({ error: 'Not Acceptable: supported types zijn JSON en HTML' });
}
next();
});
app.get('/data', (req, res) => {
res.type('json').send({ message: 'Voorbeeld data' });
});
app.listen(3000, () => console.log('Server draait op poort 3000'));
In dit voorbeeld wordt HTTP 406 actief vermeden door een duidelijke, voorliggende expressive fallback te bieden wanneer Accept-headers geen match hebben.
Een aantal richtlijnen helpt je om HTTP 406 te minimaliseren en wanneer nodig efficiënt af te handelen:
- Documenteer welke content-types en talen worden ondersteund en geef duidelijke fallback-mogelijkheden.
- Gebruik Vary: Accept, Vary: Accept-Language in responses zodat caches correct kunnen reageren op onderhandelingen.
- Overweeg om de onderhandelingen minder puntsgewijs te maken door defaulting naar breed geaccepteerde typen (bijv. text/html en application/json).
- Voeg duidelijke foutmeldingen toe die de reden van HTTP 406 uitleggen en welke stappen de client kan nemen.
- Test voortdurend in verschillende client-omgevingen en met verschillende Accept- en Language-headers.
Een foutmelding moet niet alleen technisch correct zijn, maar ook bruikbaar voor eindgebruikers en developers. Goede praktijken in dit domein zijn:
- Geef een duidelijke foutpagina of JSON-antwoord met instructies hoe de client kan aanpassen (bijv. laat weten welke Accept-types wel ondersteund worden).
- Voeg voorbeeldverzoeken of curl-commando’s toe in de documentatie zodat developers snel kunnen testen.
- Implementeer logging op naleving-niveau zodat opsporing eenvoudig blijft bij regressies.
HTTP 406 wordt vaak verward met andere statuscodes zoals 404 (Niet gevonden) of 415 (Unsupported Media Type). Het onderscheid is cruciaal:
- 404 Not Found geeft aan dat de resource niet bestaat – onafhankelijk van onderhandelingen.
- 415 Unsupported Media Type duidt op een probleem met het type van de payload die wordt verzonden, wat anders is dan wat de server kan leveren als reactie.
- 406 Not Acceptable is specifiek gerelateerd aan de tevredenheid van Accept- en andere negotiate-criteria tijdens de responsconfiguratie.
Bij API-ontwerp is het belangrijk om transparantie en voorspelbaarheid te bieden. Enkele aanbevelingen:
- Definieer expliciet welke content-types en talen beschikbaar zijn voor de API en documenteer dit duidelijk in de API-docs.
- Implementeer automatische tests die controleren of Accept-headers correct worden gehanteerd en of de fallback-mechanismen correct reageren.
- Gebruik versionering voor API’s zodat clients een stabiele representatie kunnen blijven vragen terwijl de server evolueert.
HTTP 406 heeft directe implicaties voor zowel front-end ontwikkelaars als back-end teams:
- Front-end developers moeten wellicht extra logica implementeren om Accept- en Language-criteria te manipuleren, of fallback-opties te bieden.
- QA-teams moeten testscenario’s opnemen die verschillende negotiation-parameters simuleren, inclusief edge-cases.
- Productteams moeten documenteren welke representaties in welke scenario’s beschikbaar zijn, om mislukkingen te voorkomen.
HTTP 406 Not Acceptable is een beperkende maar beheerbare toestand. Met duidelijke documentatie, juiste serverconfiguratie, en doordachte fallbacks kun je HTTP 406 effectief voorkomen of snel afhandelen. Houd Accept-headers, agenda van content-types, encodering en talen in de gaten, test grondig en zorg voor informatieve foutberichten die zowel ontwikkelaars als eindgebruikers richting geven.
Is HTTP 406 hetzelfde als 406?
Ja. HTTP 406 en 406 verwijzen naar dezelfde statuscode Not Acceptable in de context van HTTP. Het kwantificeert hetzelfde concept: onderhandelingen die geen enkele geldige representatie opleveren.
Kan HTTP 406 veroorzaakt worden door een fout in de client-code?
Ja. Een client die zeer streng of incorrect zijn Accept-criteria opstelt kan HTTP 406 veroorzaken. In dat geval is het nuttig om de clientlogica te controleren en te zorgen voor bredere of correct gekozen Accept-headers.
Wat is het verschil tussen HTTP 406 en HTTP 415?
HTTP 406 is gerelateerd aan onderhandelingen en toegestane representaties, terwijl HTTP 415 duidt op ongewenste payload-typen die de server niet accepteert. Beide geven verschillende soort problemen aan: 406 gaat over wat er geaccepteerd kan worden in de respons; 415 gaat over wat de client verzendt.
Hoe kan ik een 406 voorkomen in een openbare API?
Door duidelijke documentatie, brede defaults, en heldere fallback-paden te bieden bij onderhandelingen. Gebruik testscenario’s met verschillende Accept- en Language-headers en lever consistente fallback-responsschema’s wanneer onderhandelingen niet resulteren in een geldige representatie.
In plaats van een lastige fout in de weg te zien, kan HTTP 406 een kans zijn om de content-negotiation-ervaring te verbeteren. Door expliciete keuzes, betere documentatie en nauwere integratie tussen client en server kun je de kans op HTTP 406 aanzienlijk verkleinen en tegelijkertijd de betrouwbaarheid en gebruiksvriendelijkheid van je systemen verhogen. HTTP 406 hoeft geen blokkade te betekenen; het kan leiden tot betere afspraken en voorspelbaarere API-gedragingen.