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

  1. Use POST /mta-hook for the mail-transfer-agent callback; that is the only route this worker exposes.
  2. If you intended to send mail, call the pod-mail service instead of pod-mail-worker.
  3. Fix the health-check/probe URL to an existing path or add an explicit /healthz route if needed.
  4. 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

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.