#3815·kratos

http server Bind errors bypass middleware chain (logging/tracing/recovery not executed)

Author: robotmetaCreated Apr 20, 2026Updated Aug 12, 2026
Labelsbugstale

Title

http server Bind errors bypass middleware chain (logging/tracing/recovery not executed)


Description

In the current go-kratos HTTP server implementation, request binding (Bind) happens before middleware execution. This leads to a critical issue:

If an error occurs during the binding phase (e.g., invalid request format, missing fields, or even a panic like nil pointer dereference), the middleware chain is never executed.

As a result:

  • Logging middleware is skipped
  • Tracing middleware is skipped
  • Metrics middleware is skipped
  • Recovery middleware cannot catch panics

This effectively breaks observability and stability guarantees.


Steps to Reproduce

  1. Create a HTTP handler with a request struct

  2. Send an invalid request (e.g., malformed JSON or missing required fields)

  3. Or trigger a panic inside binding (e.g., custom binder or pointer issue)

  4. Observe that:

    • No logs are generated
    • No tracing span is recorded
    • No metrics are emitted
    • Panic is not recovered

Expected Behavior

Even if binding fails or panics occur:

  • Middleware chain should still be executed
  • Logging / tracing / metrics should capture the failure
  • Recovery middleware should handle panics

Actual Behavior

  • Binding errors short-circuit the request lifecycle
  • Middleware chain is completely bypassed
  • Observability is lost
  • Panic may crash the process (depending on context)

Root Cause Analysis

From current behavior, it appears that:

Request → Bind → Handler → Middleware

Instead of the more robust design:

Request → Middleware → Bind → Handler

Because binding occurs before middleware, any failure at this stage prevents middleware from executing.


Suggested Solutions

Option 1: Move Bind into middleware stage (Recommended)

Make binding part of the middleware chain:

Request → Middleware (including Bind) → Handler

This ensures:

  • All errors are observable
  • Recovery middleware can catch panics
  • Consistent request lifecycle

Option 2: Wrap Bind with internal middleware-like handling

If moving Bind is not feasible:

  • Wrap binding logic with:

    • logging
    • tracing
    • panic recovery

But this duplicates middleware responsibilities and is less clean.


Option 3: Provide hook / interceptor before Bind

Expose a hook like:

BeforeBind(ctx, req)

So users can inject observability logic manually.


Option 4: Ensure recovery at the outermost layer

Guarantee that panic recovery exists outside Bind, even before middleware.


Additional Context

This issue has significant impact in production systems:

  • Silent failures (no logs, no traces)
  • Observability blind spots
  • Difficult debugging
  • Potential process crashes

Environment

  • go-kratos version: (please fill)
  • Go version: (please fill)
  • OS: (please fill)

Summary

The current execution order makes the system fragile and non-observable in case of binding errors. Adjusting the lifecycle so middleware wraps the entire request (including Bind) would greatly improve robustness and observability.