Error 405 Method Not Allowed: qué significa y cómo solucionarlo

Advertisement
¿Qué es el error 405 Method Not Allowed?
405 Method Not Allowed es un código de estado HTTP que significa que el servidor conoce la dirección que pediste, pero no permite el método que usó tu petición. La RFC 9110 (sección 15.5.6) lo define como un método "known by the origin server but not supported by the target resource", es decir, conocido por el servidor de origen pero no admitido por el recurso de destino.
Toda petición HTTP tiene un método: GET para leer una página, POST para enviar un formulario o crear algo, PUT y PATCH para actualizar, DELETE para eliminar y OPTIONS para preguntar qué está permitido. Un 405 significa que la URL existe, pero no para ese verbo. Si la URL no existiera en absoluto, recibirías un 404.
Como tiene que ver con la forma en que se hizo la petición y no con una página que falta, un 405 casi siempre lo tiene que arreglar el desarrollador del sitio. Los visitantes suelen encontrárselo después de enviar un formulario o de seguir un enlace desactualizado.
Cómo se ve un error 405
| Servidor / framework | Mensaje típico |
|---|---|
| nginx | 405 Not Allowed (con nginx debajo) |
| Apache | Method Not Allowed. The requested method POST is not allowed for this URL. |
| IIS | HTTP Error 405.0 - Method Not Allowed. The page you are looking for cannot be displayed because an invalid method (HTTP verb) is being used. |
| Next.js / API | Una respuesta vacía o en JSON con estado 405, que a menudo solo se ve en DevTools |
| Consola del navegador (CORS) | Un error de CORS, porque el preflight OPTIONS recibió un 405 |
Advertisement
Paso 1: lee la cabecera Allow
Pregunta al servidor qué métodos acepta para esa URL. Envía una petición OPTIONS o repite la petición que falla mostrando las cabeceras:
# ¿Qué métodos acepta esta URL?
curl -i -X OPTIONS https://example.com/api/contact
# Repite la petición que falla y mira el estado y la cabecera Allow
curl -i -X POST https://example.com/api/contact -d 'name=test'
# HTTP/2 405
# allow: GET, HEADLa herramienta HTTP Headers de DNS Robot muestra el código de estado y las cabeceras que devuelve una URL ante una petición GET normal, lo que ayuda cuando revisas una página en el navegador y no una API.
No todos los servidores cumplen la norma. La página 405 integrada de nginx, por ejemplo, se envía sin cabecera Allow, así que en nginx tendrás que comprobar qué bloque location gestiona la URL (solución 2).
Si eres un visitante
Vuelve atrás y recarga la página, y luego envía de nuevo el formulario. Un formulario cargado desde una copia antigua en caché puede enviar los datos a una dirección que ya ha cambiado.
No actualices la página después de enviar. Actualizar una página que es el resultado de un formulario puede reenviar un POST a una URL que solo acepta GET.
Revisa la dirección por si tiene una errata, o abre la página de inicio del sitio y vuelve a navegar desde ahí.
Informa del problema. Si un formulario del sitio falla siempre, tiene que arreglarlo el propietario del sitio, así que envíale la dirección de la página.
Advertisement
Solución 1: envía el método correcto a la URL correcta
En el código, la causa más habitual es simplemente un desajuste: un formulario o una llamada fetch() usa POST cuando el endpoint solo acepta GET, o la petición va a la URL de la página en lugar de a la URL de la API. Compara el método de tu código con la cabecera Allow y con la documentación de la API.
// El endpoint solo permite POST, así que un GET (el valor predeterminado de fetch) devuelve 405
const res = await fetch("/api/contact", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Ana" }),
})
if (res.status === 405) console.log("Allowed:", res.headers.get("allow"))Solución 2: nginx devuelve 405 a los POST dirigidos a archivos estáticos
El gestor de archivos estáticos de nginx solo sirve GET y HEAD. Un POST a un archivo .html, o a un location que sirve archivos en lugar de pasar la petición a tu aplicación, recibe 405 Not Allowed. Suele ocurrir cuando el action de un formulario apunta a una página estática, o cuando un bloque location pensado para tu aplicación no coincide con la URL.
La solución real es enviar el POST a una aplicación (PHP, Node, Python) con proxy_pass o fastcgi_pass en el bloque location correcto. Comprueba qué bloque gestiona la URL:
# Los envíos de formularios deben llegar a la aplicación, no al gestor de archivos estáticos
location /api/ {
proxy_pass http://127.0.0.1:3000;
}
# Comprueba la configuración y recarga después de los cambios
# sudo nginx -t && sudo systemctl reload nginxAdvertisement
Solución 3: IIS bloquea PUT y DELETE (WebDAV)
En los servidores Windows con IIS, el módulo WebDAV se queda con los verbos PUT y DELETE, así que las API REST (ASP.NET Web API y otras) responden HTTP Error 405.0 a esas peticiones. Si no usas WebDAV, quítalo para tu sitio en web.config:
<system.webServer>
<modules>
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV" />
</handlers>
</system.webServer>Revisa también la configuración de Filtrado de solicitudes (Request Filtering) del sitio en el Administrador de IIS (pestaña Verbos HTTP), que puede denegar métodos concretos directamente (IIS los notifica como 404.6, no como 405).
Solución 4: añade el método al manejador de la ruta
Los frameworks devuelven 405 cuando una ruta existe pero no tiene un manejador para el método usado:
Next.js (App Router): un
route.tssolo responde a los métodos que exporta. Si exportaGETpero noPOST, un POST devuelve 405. Añadeexport async function POST(request: Request) { … }.Flask: las rutas solo aceptan GET de forma predeterminada. Usa
@app.route("/contact", methods=["GET", "POST"]).Django: las vistas basadas en clases devuelven 405 para los métodos que no tienen un manejador (añade un método
post()), y el decoradorrequire_http_methodshace lo mismo.Express: de forma predeterminada, un método sin ruta coincidente termina en un 404, no en un 405. Si tu API debe devolver 405, añade un manejador comodín que defina la cabecera
Allow.
Advertisement
Solución 5: gestiona las peticiones de preflight CORS (OPTIONS)
Cuando una página web llama a una API de otro dominio con JSON o con cabeceras personalizadas, el navegador envía primero una petición OPTIONS de preflight (verificación previa). Si la API responde a esa petición OPTIONS con un 405, el navegador informa de un error de CORS y nunca envía la petición real, aunque el endpoint real habría funcionado.
Haz que la API responda a OPTIONS en esas rutas con un 204 o un 200 y las cabeceras Access-Control-Allow-Methods y Access-Control-Allow-Headers correctas. La mayoría de los frameworks tienen un middleware de CORS que lo hace por ti. Por ejemplo, la propia API de DNS Lookup de DNS Robot responde al preflight con un 204 y las cabeceras CORS, para que los navegadores puedan llamarla desde cualquier sitio.
405 frente a 400, 403, 404 y 501
| Código | Significado |
|---|---|
| 405 Method Not Allowed | La URL existe, pero no para este método |
| 400 Bad Request | La petición en sí está mal formada |
| 403 Forbidden | El servidor te entendió, pero no permite el acceso |
| 404 Not Found | No existe nada en esta URL |
| 501 Not Implemented | El servidor no admite este método para ninguna URL |
Guías relacionadas: 400 Bad Request, 403 Forbidden y 401 Unauthorized.
Comprueba qué devuelve una URL
El Verificador de Cabeceras HTTP de DNS Robot muestra el código de estado y las cabeceras de respuesta de cualquier URL, para que puedas confirmar un 405 y ver qué software de servidor hay detrás.
Probar Verificador de Cabeceras HTTPAdvertisement
Preguntas frecuentes
Significa que el servidor reconoce la URL pero no acepta el método HTTP usado, como un POST enviado a una página que solo permite GET. La respuesta debería incluir una cabecera Allow con los métodos que sí acepta esa URL.