XTLS/Xray-core · error

failed to build mask with type + mask.Type

Error message

failed to build mask with type  + mask.Type

What it means

Thrown when a TCP mask entry under streamSettings.finalMask.tcp fails to build (mask.Build(true) errors). The error text interpolates mask.Type, so it tells you which mask implementation rejected its own configuration (e.g. an unrecognized or misconfigured TCP mask type). It stops config compilation immediately.

Source

Thrown at infra/conf/transport_internet.go:207

		}
		config.TransportSettings = append(config.TransportSettings, &internet.TransportConfig{
			ProtocolName: "hysteria",
			Settings:     serial.ToTypedMessage(hs),
		})
	}
	if c.SocketSettings != nil {
		ss, err := c.SocketSettings.Build()
		if err != nil {
			return nil, errors.New("Failed to build sockopt.").Base(err)
		}
		config.SocketSettings = ss
	}

	if c.FinalMask != nil {
		for _, mask := range c.FinalMask.Tcp {
			u, err := mask.Build(true)
			if err != nil {
				return nil, errors.New("failed to build mask with type ", mask.Type).Base(err)
			}
			config.Tcpmasks = append(config.Tcpmasks, serial.ToTypedMessage(u))
		}
		for _, mask := range c.FinalMask.Udp {
			u, err := mask.Build(false)
			if err != nil {
				return nil, errors.New("failed to build mask with type ", mask.Type).Base(err)
			}
			config.Udpmasks = append(config.Udpmasks, serial.ToTypedMessage(u))
		}
		if c.FinalMask.QuicParams != nil {
			profile := strings.ToLower(c.FinalMask.QuicParams.BbrProfile)
			switch profile {
			case "", string(bbr.ProfileConservative), string(bbr.ProfileStandard), string(bbr.ProfileAggressive):
				if profile == "" {
					profile = string(bbr.ProfileStandard)
				}
			default:

View on GitHub (pinned to 7d214f8b09)

Solutions

  1. Check the mask.Type value in the error against the registered TCP mask types in the codebase; fix typos or unsupported types.
  2. Validate the per-type fields required by that mask implementation.
  3. Remove the offending mask entry to isolate whether other mask entries build fine.

Example fix

// before
"finalMask": { "tcp": [ { "type": "typoMask", "window": 10 } ] }
// after
"finalMask": { "tcp": [ { "type": "windowMask", "window": 10 } ] } // use a registered type
Defensive patterns

Strategy: validation

Validate before calling

var validTcpMaskTypes = map[string]bool{"window": true /* ...populate from this build's registry... */}

func tcpMasksValid(fm map[string]any) bool {
    tcp, _ := fm["tcp"].([]any)
    for _, m := range tcp {
        mm, _ := m.(map[string]any)
        t, _ := mm["type"].(string)
        if !validTcpMaskTypes[t] { return false }
    }
    return true
}

Type guard

func isFinalMaskTcpList(fm map[string]any) bool {
    _, ok := fm["tcp"].([]any)
    return ok
}

Try / catch

if err := doc.Build(); err != nil {
    if strings.HasPrefix(err.Error(), "failed to build mask with type") {
        // extract the type token from the message and report which entry failed
    }
    return err
}

Prevention

When it happens

Trigger: Config contains "finalMask": { "tcp": [ { "type": "<something>", ... } ] } and the mask's Build() returns an error for that type's parameters.

Common situations: Using a mask type name not registered/supported by this build; supplying wrong per-type fields; configs ported from a fork with extra mask types.

Related errors


AI-assisted analysis of XTLS/Xray-core@7d214f8b09 (2026-08-15). Data as JSON: /api/errors/3f093aa728a8a03d. Report an issue: GitHub.