🔧 Error Fixes
· 2 min read
Last updated on

Hono: 404 Not Found for All Routes — How to Fix It


404 Not Found

What causes this

Every route in your Hono app returns 404. This usually means Hono isn’t seeing your route registrations, or the routes are registered on a different path than you’re requesting. Common causes:

  • Routes are registered after the app is exported
  • The basePath is set and you’re not including it in your requests
  • The HTTP method doesn’t match (GET vs POST)
  • In Cloudflare Workers, the wrangler.toml routes don’t match
  • You’re exporting the wrong object

Fix 1: Register routes before exporting

import { Hono } from 'hono';

const app = new Hono();

// ✅ Register routes BEFORE the export
app.get('/', (c) => c.text('Hello'));
app.get('/api/users', (c) => c.json({ users: [] }));
app.post('/api/users', (c) => c.json({ created: true }));

export default app;

If you’re splitting routes into separate files, make sure they’re imported and mounted:

import { Hono } from 'hono';
import users from './routes/users';

const app = new Hono();
app.route('/api/users', users);

export default app;

Fix 2: Check the basePath

If you set a basePath, all routes are prefixed:

// With basePath, routes are prefixed
const app = new Hono().basePath('/api');
app.get('/users', handler);
// Actual URL: GET /api/users — NOT /users

// Without basePath
const app = new Hono();
app.get('/api/users', handler);
// Actual URL: GET /api/users

Make sure your requests include the base path.

Fix 3: Check the HTTP method

Hono is strict about methods. A POST request won’t match a GET route:

app.get('/api/data', handler);   // Only matches GET
app.post('/api/data', handler);  // Only matches POST

// If you want to match all methods:
app.all('/api/data', handler);

Test with the right method:

# GET request
curl http://localhost:8787/api/data

# POST request
curl -X POST http://localhost:8787/api/data

Fix 4: Cloudflare Workers — check wrangler.toml

If deploying to Cloudflare Workers, make sure your routes are configured:

# wrangler.toml
name = "my-api"
main = "src/index.ts"

# If using custom domains
[triggers]
routes = ["api.example.com/*"]

Also check that main points to the file that exports your Hono app.

Fix 5: Check you’re exporting the right thing

// ❌ Exporting the Hono constructor, not the app instance
export default Hono;

// ❌ Exporting before adding routes
const app = new Hono();
export default app;
app.get('/', handler);  // Too late!

// ✅ Correct
const app = new Hono();
app.get('/', handler);
export default app;

How to prevent it

  • Always register all routes before the export default statement
  • Use app.all('*', (c) => c.text('Not found', 404)) as a catch-all at the end to confirm Hono is running
  • Test routes locally with curl or a tool like our HTTP header analyzer before deploying
  • If using basePath, document it in your README so teammates know the full URL structure