XTLS/Xray-core · error · errors.Error
missing inbound or outbound metadata from context
Error message
missing inbound or outbound metadata from context
What it means
fillRequestHeader needs inbound.Source and the last outbound's Target to template headers (e.g. X-Real-IP style values). If session.InboundFromContext returns nil or the outbounds slice's tail is nil, header rendering cannot proceed and this error is returned (then wrapped as "failed to fill out header" by the caller).
Source
Thrown at proxy/http/client.go:177
if err := task.Run(ctx, requestFunc, responseDonePost); err != nil {
return errors.New("connection ends").Base(err)
}
return nil
}
// fillRequestHeader will fill out the template of the headers
func fillRequestHeader(ctx context.Context, header []*Header) ([]*Header, error) {
if len(header) == 0 {
return header, nil
}
inbound := session.InboundFromContext(ctx)
outbounds := session.OutboundsFromContext(ctx)
ob := outbounds[len(outbounds)-1]
if inbound == nil || ob == nil {
return nil, errors.New("missing inbound or outbound metadata from context")
}
data := struct {
Source net.Destination
Target net.Destination
}{
Source: inbound.Source,
Target: ob.Target,
}
filled := make([]*Header, len(header))
for i, h := range header {
tmpl, err := template.New(h.Key).Parse(h.Value)
if err != nil {
return nil, err
}
var buf bytes.Buffer
View on GitHub (pinned to 7d214f8b09)
Solutions
- Only configure settings.headers when all traffic through this outbound comes from standard inbounds that attach session data
- In tests, inject session.ContextWithInbound/ContextWithOutbounds before calling Process
- Remove headers if the upstream proxy does not require them
Example fix
```go
ctx = session.ContextWithInbound(ctx, &session.Inbound{ Source: src })
ctx = session.ContextWithOutbounds(ctx, &session.Outbound{ Target: dest })
// then Process
``` Defensive patterns
Strategy: validation
Validate before calling
```go
ctx = session.ContextWithInbound(ctx, &session.Inbound{Source: src})
ctx = session.ContextWithOutbounds(ctx, &session.Outbound{Target: target})
// only now call Process with headers enabled
``` Type guard
```go
func hasSessionMetadata(ctx context.Context) bool {
in := session.InboundFromContext(ctx)
obs := session.OutboundsFromContext(ctx)
return in != nil && len(obs) > 0 && obs[len(obs)-1] != nil
}
``` Prevention
- Inject inbound/outbound context in tests
- Avoid headers on outbounds fed by exotic dispatchers
- Guard fillRequestHeader callers with metadata checks
When it happens
Trigger: settings.headers[] is non-empty AND the session context lacks inbound metadata — e.g. synthetic contexts built by tests or outbounds invoked outside a normal dispatcher flow; or an empty outbounds slice making outbounds[len-1] panic-adjacent/nil.
Common situations: Unit tests invoking Process with a bare context; custom dispatchers that strip session metadata; headers configured globally but traffic originating from unusual inbounds.
Related errors
- target not specified.
- failed to fill out header
- outbound metadata not found
- failed to add new session
- empty HTTP header value: + key
AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15).
Data as JSON: /api/errors/4d1933b36e273cfb.
Report an issue: GitHub.