v2fly/v2ray-core · error

no inbound metadata

Error message

no inbound metadata

What it means

This is a hard Go panic raised in the VLESS inbound's Process() right after the VLESS request header is decoded and accepted. The handler requires session.Inbound metadata in the context; that value is attached by the proxyman inbound worker (app/proxyman/inbound/worker.go, session.ContextWithInbound) when a connection arrives through a registered inbound. A nil result from session.InboundFromContext(ctx) means the proxy was invoked outside that pipeline, so it aborts the process.

Source

Thrown at proxy/vless/inbound/inbound.go:368

			log.Record(&log.AccessMessage{
				From:   connection.RemoteAddr(),
				To:     "",
				Status: log.AccessRejected,
				Reason: err,
			})
			err = newError("invalid request from ", connection.RemoteAddr()).Base(err).AtInfo()
		}
		return err
	}

	if err := connection.SetReadDeadline(time.Time{}); err != nil {
		newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid)
	}
	newError("received request for ", request.Destination()).AtInfo().WriteToLog(sid)

	inbound := session.InboundFromContext(ctx)
	if inbound == nil {
		panic("no inbound metadata")
	}
	inbound.User = request.User

	responseAddons := &encoding.Addons{}

	if request.Command != protocol.RequestCommandMux {
		ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
			From:   connection.RemoteAddr(),
			To:     request.Destination(),
			Status: log.AccessAccepted,
			Reason: "",
			Email:  request.User.Email,
		})
	}

	sessionPolicy = h.policyManager.ForLevel(request.User.Level)
	ctx, cancel := context.WithCancel(ctx)
	timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)

View on GitHub (pinned to db12914161)

Solutions

  1. Make sure the VLESS inbound is reached through a configured inbound handler so proxyman's worker stamps the context (see session.ContextWithInbound calls in app/proxyman/inbound/worker.go).
  2. If you must call Process() directly, attach inbound metadata yourself first: ctx = session.ContextWithInbound(ctx, &session.Inbound{Tag: ...}).
  3. Copy the established pattern from app/tun/handler_tcp.go:89 or app/reverse/bridge.go:105 when building custom entry points.
  4. Add a recover() guard in custom embedding layers and fail the single connection instead of crashing the process during bring-up of the new path.

Example fix

// before
ctx := context.WithValue(context.Background(), myKey, myVal)
err = s.vlessInbound.Process(ctx, link, connection) // panic: no inbound metadata

// after
ctx = session.ContextWithInbound(ctx, &session.Inbound{
    Tag:    "vless-in",
    Source: net.DestinationFromAddr(connection.RemoteAddr()),
})
err = s.vlessInbound.Process(ctx, link, connection)
Defensive patterns

Strategy: validation

Validate before calling

// ensure inbound metadata exists before invoking the VLESS inbound:
if session.InboundFromContext(ctx) == nil {
    ctx = session.ContextWithInbound(ctx, &session.Inbound{
        Tag:    "vless-in",
        Source: net.DestinationFromAddr(connection.RemoteAddr()),
    })
}
err := vlessInbound.Process(ctx, link, connection)

Type guard

func hasInboundMetadata(ctx context.Context) bool {
    return session.InboundFromContext(ctx) != nil
}

Try / catch

defer func() {
    if r := recover(); r != nil {
        log.Printf("vless inbound panicked (likely missing session.Inbound in ctx): %v\n%s", r, debug.Stack())
    }
}()
err := vlessInbound.Process(ctx, link, connection)

Prevention

When it happens

Trigger: Calling vless inbound Process() with a context that was never passed through proxyman's worker (unit tests, custom dispatchers); a custom transport/stream dispatch that constructs its own ctx and calls the proxy directly; context cloning/replacement code between connection accept and Process() that loses the inbound value; calling the handler from a new code path (e.g. an API-triggered socket) without copying the pattern used in app/tun/handler_tcp.go (which does set session.Inbound).

Common situations: Developers writing handler tests with context.Background(); embedding the VLESS inbound into a custom server that accepts raw TLS/TCP connections itself; forks that add alternative listeners (systemd socket activation, TUN, gVisor netstack) and forget the session.ContextWithInbound call; refactors that wrap the context with a fresh non-Derived context.

Related errors


AI-assisted analysis of v2fly/v2ray-core@db12914161 (2026-08-15). Data as JSON: /api/errors/a1069c0c2e41a84a. Report an issue: GitHub.