hcengineering/platform · warning
Not found
Error message
Not found
What it means
The pod-mail-worker Express app has a catch-all 404 handler that responds { message: 'Not found' } for any request not matched by an earlier route. Only /mta-hook (and any earlier middleware) is defined, so hitting any other path or verb yields this JSON 404. It signals the URL/method does not exist on this worker.
Source
Thrown at services/mail/pod-mail-worker/src/index.ts:76
limit: config.mailSizeLimit
})
)
const catchError = (fn: RequestHandler) => (req: Request, res: Response, next: NextFunction) => {
void (async () => {
try {
await fn(req, res, ctx)
} catch (error: any) {
ctx.error('Failed to handle request', { method: req.method, path: req.path, error })
next(error)
}
})()
}
app.post('/mta-hook', catchError(handleMtaHook))
app.use((_req, res, _next) => {
res.status(404).send({ message: 'Not found' })
})
app.use((err: any, req: Request, res: any, _next: any) => {
ctx.error(err)
if (req.path === '/mta-hook') {
// Any error in the mta-hook should not prevent the mail server from handling emails
// At least the PayloadTooLargeError falls here before reacing our code
res.status(200).send({ action: 'accept' })
return
}
res.status(500).send({ message: err.message })
})
const server = app.listen(config.port, () => {
ctx.info('server started', {
...config,
secret: config.secret !== undefined ? '(stripped)' : undefined,
hookToken: config.hookToken !== undefined ? '(stripped)' : undefined,View on GitHub (pinned to 63e28dc964)
Solutions
- Use POST /mta-hook for the mail-transfer-agent callback; that is the only route this worker exposes.
- If you intended to send mail, call the pod-mail service instead of pod-mail-worker.
- Fix the health-check/probe URL to an existing path or add an explicit /healthz route if needed.
- Check for typos or an extra path prefix (e.g. double slashes) in the configured service URL.
Example fix
// before
await fetch(`${workerUrl}/send-mail`, ...) // worker has no such route -> 404 Not found
// after
await fetch(`${workerUrl}/mta-hook`, { method: 'POST', ... }) Defensive patterns
Strategy: validation
Validate before calling
const WORKER_ROUTES = new Set(['/mta-hook'])
function assertWorkerUrl(url: string, method = 'POST'): void {
const p = new URL(url).pathname.replace(/\/$/, '')
if (!WORKER_ROUTES.has(p)) throw new Error(`${method} ${p} does not exist on pod-mail-worker (only /mta-hook)`)
} Type guard
function isMtaHookPath(pathname: string): boolean {
return pathname.replace(/\/$/, '') === '/mta-hook'
} Try / catch
const res = await fetch(url, opts)
if (res.status === 404) {
const body = await res.json().catch(() => null)
throw new Error(`wrong service/path: ${body?.message ?? 'not found'} — pod-mail-worker only exposes POST /mta-hook`)
} Prevention
- Only send mail via the pod-mail service, not pod-mail-worker.
- Register health probes against an existing path or add a /healthz route.
- Double-check service URLs for typos and trailing path segments.
- Match the HTTP verb: /mta-hook expects POST.
When it happens
Trigger: Any request to the mail worker on a path other than POST /mta-hook — e.g. GET /, /healthz, /send, or POST to a misspelled path like /mta-hook/ with a trailing segment not registered.
Common situations: Health-check probes pointed at a path that does not exist; confusing pod-mail (which exposes send-mail endpoints) with pod-mail-worker (which only exposes /mta-hook); typos in internal service URLs; calling with the wrong HTTP verb on /mta-hook.
Related errors
AI-assisted analysis of hcengineering/platform@63e28dc964 (2026-08-29).
Data as JSON: /api/errors/ea955dfa370dd283.
Report an issue: GitHub.