{"record":{"id":"a5848243daa53f6d","repo":"XTLS/Xray-core","slug":"failed-to-fill-out-header","errorCode":null,"errorMessage":"failed to fill out header","messagePattern":"failed to fill out header","errorType":"exception","errorClass":"errors.Error","httpStatus":null,"severity":"error","filePath":"proxy/http/client.go","lineNumber":100,"sourceCode":"\t}\n\n\tserver := c.server\n\tdest := server.Destination\n\tuser := server.User\n\tvar conn stat.Connection\n\n\tmbuf, _ := link.Reader.ReadMultiBuffer()\n\tlen := mbuf.Len()\n\tfirstPayload := bytespool.Alloc(len)\n\tmbuf, _ = buf.SplitBytes(mbuf, firstPayload)\n\tfirstPayload = firstPayload[:len]\n\n\tbuf.ReleaseMulti(mbuf)\n\tdefer bytespool.Free(firstPayload)\n\n\theader, err := fillRequestHeader(ctx, c.header)\n\tif err != nil {\n\t\treturn errors.New(\"failed to fill out header\").Base(err)\n\t}\n\n\tif err := retry.ExponentialBackoff(5, 100).On(func() error {\n\t\tnetConn, err := setUpHTTPTunnel(ctx, dest, targetAddr, user, dialer, header, firstPayload)\n\t\tif netConn != nil {\n\t\t\tif _, ok := netConn.(*http2Conn); !ok {\n\t\t\t\tif _, err := netConn.Write(firstPayload); err != nil {\n\t\t\t\t\tnetConn.Close()\n\t\t\t\t\treturn err\n\t\t\t\t}\n\t\t\t}\n\t\t\tconn = stat.Connection(netConn)\n\t\t}\n\t\treturn err\n\t}); err != nil {\n\t\treturn errors.New(\"failed to find an available destination\").Base(err)\n\t}\n","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/XTLS/Xray-core/blob/7d214f8b094f75322fa3990f8aadad1c912f24f5/proxy/http/client.go#L82-L118","documentation":"Before opening the tunnel, the HTTP outbound templates the configured custom headers via fillRequestHeader. That helper can fail on missing session metadata (see the dedicated error for that) or on template evaluation problems; the outer Process wraps any such failure as \"failed to fill out header\".","triggerScenarios":"settings.headers[] configured on the HTTP outbound while the session context lacks inbound/outbound metadata, or a header value using template variables that cannot be evaluated for the current request.","commonSituations":"Header templating (e.g. X-Forwarded-For style headers) configured on an outbound that also handles traffic from inbounds which do not attach session metadata; empty headers array mixed with odd configs.","solutions":["Check the Base error from fillRequestHeader — it distinguishes missing metadata from other failures","Ensure the inbound attaches proper session metadata (stock Xray inbounds do)","If headers are not needed by the upstream proxy, remove settings.headers","Verify header template syntax matches supported variables (source, target)"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"```go\nif len(cfg.Header) > 0 {\n    if session.InboundFromContext(ctx) == nil {\n        // skip header templating or attach metadata first\n    }\n}\n```","typeGuard":null,"tryCatchPattern":"```go\nif _, err := fillRequestHeader(ctx, headers); err != nil {\n    if strings.Contains(err.Error(), \"missing inbound or outbound\") { /* attach session metadata */ }\n}\n```","preventionTips":["Only set headers when inbounds provide session metadata","Test header templates with real dispatcher flows","Remove headers the proxy does not need"],"tags":["http-outbound","headers","template","xray"],"backgroundTag":null,"analyzedSha":"7d214f8b094f75322fa3990f8aadad1c912f24f5","analyzedAt":"2026-08-15T14:26:24.325Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}